Annotation of sys/arch/sparc64/dev/auxio.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: auxio.c,v 1.7 2005/03/09 18:41:48 miod Exp $ */
2: /* $NetBSD: auxio.c,v 1.1 2000/04/15 03:08:13 mrg Exp $ */
3:
4: /*
5: * Copyright (c) 2000 Matthew R. Green
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. The name of the author may not be used to endorse or promote products
17: * derived from this software without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
32: /*
33: * AUXIO registers support on the sbus & ebus2.
34: */
35:
36: #include <sys/param.h>
37: #include <sys/systm.h>
38: #include <sys/errno.h>
39: #include <sys/device.h>
40: #include <sys/timeout.h>
41: #include <sys/kernel.h>
42:
43: #include <machine/autoconf.h>
44: #include <machine/cpu.h>
45:
46: #include <sparc64/dev/ebusreg.h>
47: #include <sparc64/dev/ebusvar.h>
48: #include <sparc64/dev/sbusvar.h>
49: #include <sparc64/dev/auxioreg.h>
50: #include <sparc64/dev/auxiovar.h>
51:
52: #define AUXIO_ROM_NAME "auxio"
53:
54: /*
55: * ebus code.
56: */
57: int auxio_ebus_match(struct device *, void *, void *);
58: void auxio_ebus_attach(struct device *, struct device *, void *);
59: int auxio_sbus_match(struct device *, void *, void *);
60: void auxio_sbus_attach(struct device *, struct device *, void *);
61: void auxio_attach_common(struct auxio_softc *);
62:
63: struct cfattach auxio_ebus_ca = {
64: sizeof(struct auxio_softc), auxio_ebus_match, auxio_ebus_attach
65: };
66:
67: struct cfattach auxio_sbus_ca = {
68: sizeof(struct auxio_softc), auxio_sbus_match, auxio_sbus_attach
69: };
70:
71: struct cfdriver auxio_cd = {
72: NULL, "auxio", DV_DULL
73: };
74:
75: void auxio_led_blink(void *, int);
76:
77: int
78: auxio_ebus_match(parent, cf, aux)
79: struct device *parent;
80: void *cf;
81: void *aux;
82: {
83: struct ebus_attach_args *ea = aux;
84:
85: return (strcmp(AUXIO_ROM_NAME, ea->ea_name) == 0);
86: }
87:
88: void
89: auxio_ebus_attach(parent, self, aux)
90: struct device *parent, *self;
91: void *aux;
92: {
93: struct auxio_softc *sc = (struct auxio_softc *)self;
94: struct ebus_attach_args *ea = aux;
95:
96: if (ea->ea_nregs < 1 || ea->ea_nvaddrs < 1) {
97: printf(": no registers??\n");
98: return;
99: }
100:
101: sc->sc_tag = ea->ea_memtag;
102:
103: if (ea->ea_nregs != 5 || ea->ea_nvaddrs != 5) {
104: printf(": not 5 (%d) registers, only setting led",
105: ea->ea_nregs);
106: sc->sc_flags = AUXIO_LEDONLY|AUXIO_EBUS;
107: } else {
108: sc->sc_flags = AUXIO_EBUS;
109: if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[2],
110: sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
111: &sc->sc_freq)) {
112: printf(": unable to map freq\n");
113: return;
114: }
115: if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[3],
116: sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
117: &sc->sc_scsi)) {
118: printf(": unable to map SCSI\n");
119: return;
120: }
121: if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[4],
122: sizeof(u_int32_t), BUS_SPACE_MAP_PROMADDRESS,
123: &sc->sc_temp)) {
124: printf(": unable to map temp\n");
125: return;
126: }
127: }
128:
129: if (bus_space_map(sc->sc_tag, ea->ea_vaddrs[0], sizeof(u_int32_t),
130: BUS_SPACE_MAP_PROMADDRESS, &sc->sc_led)) {
131: printf(": unable to map LED\n");
132: return;
133: }
134:
135: auxio_attach_common(sc);
136: }
137:
138: int
139: auxio_sbus_match(parent, cf, aux)
140: struct device *parent;
141: void *cf;
142: void *aux;
143: {
144: struct sbus_attach_args *sa = aux;
145:
146: return (strcmp(AUXIO_ROM_NAME, sa->sa_name) == 0);
147: }
148:
149: void
150: auxio_sbus_attach(parent, self, aux)
151: struct device *parent, *self;
152: void *aux;
153: {
154: struct auxio_softc *sc = (struct auxio_softc *)self;
155: struct sbus_attach_args *sa = aux;
156:
157: sc->sc_tag = sa->sa_bustag;
158:
159: if (sa->sa_nreg < 1 || sa->sa_npromvaddrs < 1) {
160: printf(": no registers??\n");
161: return;
162: }
163:
164: if (sa->sa_nreg != 1 || sa->sa_npromvaddrs != 1) {
165: printf(": not 1 (%d/%d) registers??", sa->sa_nreg, sa->sa_npromvaddrs);
166: return;
167: }
168:
169: /* sbus auxio only has one set of registers */
170: sc->sc_flags = AUXIO_LEDONLY|AUXIO_SBUS;
171: if (bus_space_map(sc->sc_tag, sa->sa_promvaddr, 1,
172: BUS_SPACE_MAP_PROMADDRESS, &sc->sc_led)) {
173: printf(": couldn't map registers\n");
174: return;
175: }
176:
177: auxio_attach_common(sc);
178: }
179:
180: void
181: auxio_attach_common(sc)
182: struct auxio_softc *sc;
183: {
184: sc->sc_blink.bl_func = auxio_led_blink;
185: sc->sc_blink.bl_arg = sc;
186: blink_led_register(&sc->sc_blink);
187: printf("\n");
188: }
189:
190: void
191: auxio_led_blink(void *vsc, int on)
192: {
193: struct auxio_softc *sc = vsc;
194: u_int32_t led;
195: int s;
196:
197: s = splhigh();
198:
199: if (sc->sc_flags & AUXIO_EBUS)
200: led = letoh32(bus_space_read_4(sc->sc_tag, sc->sc_led, 0));
201: else
202: led = bus_space_read_1(sc->sc_tag, sc->sc_led, 0);
203:
204: if (on)
205: led |= AUXIO_LED_LED;
206: else
207: led &= ~AUXIO_LED_LED;
208:
209: if (sc->sc_flags & AUXIO_EBUS)
210: bus_space_write_4(sc->sc_tag, sc->sc_led, 0, htole32(led));
211: else
212: bus_space_write_1(sc->sc_tag, sc->sc_led, 0, led);
213:
214: splx(s);
215: }
216:
217: int
218: auxio_fd_control(u_int32_t bits)
219: {
220: struct auxio_softc *sc;
221: u_int32_t led;
222:
223: if (auxio_cd.cd_ndevs == 0) {
224: return ENXIO;
225: }
226:
227: /*
228: * XXX This does not handle > 1 auxio correctly.
229: * We'll assume the floppy drive is tied to first auxio found.
230: */
231: sc = (struct auxio_softc *)auxio_cd.cd_devs[0];
232: if (sc->sc_flags & AUXIO_EBUS)
233: led = letoh32(bus_space_read_4(sc->sc_tag, sc->sc_led, 0));
234: else
235: led = bus_space_read_1(sc->sc_tag, sc->sc_led, 0);
236:
237: led = (led & ~AUXIO_LED_FLOPPY_MASK) | bits;
238:
239: if (sc->sc_flags & AUXIO_EBUS)
240: bus_space_write_4(sc->sc_tag, sc->sc_led, 0, htole32(led));
241: else
242: bus_space_write_1(sc->sc_tag, sc->sc_led, 0, led);
243:
244: return 0;
245: }
CVSweb