Annotation of sys/arch/sparc/dev/scf.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: scf.c,v 1.10 2006/03/15 20:03:06 miod Exp $ */
2:
3: /*
4: * Copyright (c) 1999 Jason L. Wright (jason@thought.net)
5: * All rights reserved.
6: *
7: * This software was developed by Jason L. Wright under contract with
8: * RTMX Incorporated (http://www.rtmx.com).
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
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
21: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29: * POSSIBILITY OF SUCH DAMAGE.
30: */
31:
32: /*
33: * Driver for the flash memory and sysconfig registers found on Force CPU-5V
34: * boards.
35: */
36:
37: #include <sys/param.h>
38: #include <sys/systm.h>
39: #include <sys/kernel.h>
40: #include <sys/errno.h>
41: #include <sys/ioctl.h>
42: #include <sys/mbuf.h>
43: #include <sys/socket.h>
44: #include <sys/syslog.h>
45: #include <sys/device.h>
46: #include <sys/malloc.h>
47: #include <sys/timeout.h>
48:
49: #include <machine/autoconf.h>
50: #include <sparc/cpu.h>
51: #include <sparc/sparc/cpuvar.h>
52: #include <machine/scfio.h>
53: #include <sparc/dev/scfreg.h>
54:
55: int scfmatch(struct device *, void *, void *);
56: void scfattach(struct device *, struct device *, void *);
57:
58: int scfopen(dev_t, int, int, struct proc *);
59: int scfclose(dev_t, int, int, struct proc *);
60: int scfioctl(dev_t, u_long, caddr_t, int, struct proc *);
61:
62: struct scf_softc {
63: struct device sc_dv; /* base device */
64: struct scf_regs *sc_regs; /* our registers */
65: int sc_open;
66: int sc_tick;
67: struct timeout sc_blink_tmo; /* for scfblink() */
68: };
69:
70: struct cfattach scf_ca = {
71: sizeof (struct scf_softc), scfmatch, scfattach
72: };
73:
74: struct cfdriver scf_cd = {
75: NULL, "scf", DV_DULL
76: };
77:
78: extern int sparc_led_blink;
79:
80: static const u_int8_t scf_pattern[] = {
81: SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_F,
82: SSLDCR_B|SSLDCR_C,
83: SSLDCR_A|SSLDCR_B|SSLDCR_D|SSLDCR_E|SSLDCR_G,
84: SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_G,
85: SSLDCR_B|SSLDCR_C|SSLDCR_F|SSLDCR_G,
86: SSLDCR_A|SSLDCR_C|SSLDCR_D|SSLDCR_F|SSLDCR_G,
87: SSLDCR_A|SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_F|SSLDCR_G,
88: SSLDCR_A|SSLDCR_B|SSLDCR_C,
89: SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_F|SSLDCR_G,
90: SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_F|SSLDCR_G,
91: SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_E|SSLDCR_F|SSLDCR_G,
92: SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_F|SSLDCR_G,
93: SSLDCR_A|SSLDCR_D|SSLDCR_E|SSLDCR_F,
94: SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_G,
95: SSLDCR_A|SSLDCR_D|SSLDCR_E|SSLDCR_F|SSLDCR_G,
96: SSLDCR_A|SSLDCR_E|SSLDCR_F|SSLDCR_G,
97: };
98:
99: int
100: scfmatch(parent, vcf, aux)
101: struct device *parent;
102: void *vcf, *aux;
103: {
104: struct confargs *ca = aux;
105: register struct romaux *ra = &ca->ca_ra;
106:
107: if (strcmp("sysconfig", ra->ra_name))
108: return (0);
109:
110: return (1);
111: }
112:
113: void
114: scfattach(parent, self, aux)
115: struct device *parent, *self;
116: void *aux;
117: {
118: struct confargs *ca = aux;
119: struct scf_softc *sc = (struct scf_softc *)self;
120: char *s;
121:
122: /* map registers */
123: if (ca->ca_ra.ra_nreg != 1) {
124: printf(": expected 1 register, got %d\n", ca->ca_ra.ra_nreg);
125: return;
126: }
127:
128: sc->sc_regs = mapiodev(&(ca->ca_ra.ra_reg[0]), 0,
129: ca->ca_ra.ra_reg[0].rr_len);
130:
131: s = getpropstring(ca->ca_ra.ra_node, "model");
132: printf(": model %s\n", s);
133:
134: sc->sc_regs->led1 &= ~LED_MASK;
135: sc->sc_regs->led2 &= ~LED_MASK;
136: sc->sc_regs->ssldcr = 0;
137:
138: timeout_set(&sc->sc_blink_tmo, scfblink, 0);
139:
140: if (sparc_led_blink)
141: scfblink(0);
142: }
143:
144: int
145: scfopen(dev, flags, mode, p)
146: dev_t dev;
147: int flags;
148: int mode;
149: struct proc *p;
150: {
151: struct scf_softc *sc;
152: int card = 0;
153:
154: if (card >= scf_cd.cd_ndevs)
155: return (ENXIO);
156: sc = scf_cd.cd_devs[card];
157: if (sc == NULL)
158: return (ENXIO);
159: if (sc->sc_open)
160: return (EBUSY);
161:
162: sc->sc_open = 1;
163: return (0);
164: }
165:
166: int
167: scfclose(dev, flags, mode, p)
168: dev_t dev;
169: int flags;
170: int mode;
171: struct proc *p;
172: {
173: struct scf_softc *sc;
174: int card = 0;
175:
176: sc = scf_cd.cd_devs[card];
177: sc->sc_open = 0;
178: return (0);
179: }
180:
181: int
182: scfioctl(dev, cmd, data, flags, p)
183: dev_t dev;
184: u_long cmd;
185: caddr_t data;
186: int flags;
187: struct proc *p;
188: {
189: struct scf_softc *sc = scf_cd.cd_devs[0];
190: u_int8_t *ptr = (u_int8_t *)data, c;
191: int error = 0;
192:
193: switch (cmd) {
194: case SCFIOCSLED1:
195: sc->sc_regs->led1 = LED_MASK | (*ptr);
196: break;
197: case SCFIOCGLED1:
198: *ptr = sc->sc_regs->led1 & (LED_COLOR_MASK | LED_BLINK_MASK);
199: break;
200: case SCFIOCSLED2:
201: sc->sc_regs->led2 = LED_MASK | (*ptr);
202: break;
203: case SCFIOCGLED2:
204: *ptr = sc->sc_regs->led2 & (LED_COLOR_MASK | LED_BLINK_MASK);
205: break;
206: case SCFIOCSLED7:
207: sc->sc_regs->ssldcr = *ptr;
208: break;
209: case SCFIOCGLED7:
210: *ptr = sc->sc_regs->ssldcr;
211: break;
212: case SCFIOCGROT:
213: *ptr = sc->sc_regs->rssr;
214: break;
215: case SCFIOCSFMCTRL:
216: if ((*ptr) & SCF_FMCTRL_SELROM)
217: sc->sc_regs->fmpcr1 |= FMPCR1_SELROM;
218: else
219: sc->sc_regs->fmpcr1 &= ~FMPCR1_SELROM;
220:
221: if ((*ptr) & SCF_FMCTRL_SELBOOT)
222: sc->sc_regs->fmpcr2 |= FMPCR2_SELBOOT;
223: else
224: sc->sc_regs->fmpcr2 &= ~FMPCR2_SELBOOT;
225:
226: if ((*ptr) & SCF_FMCTRL_WRITEV)
227: sc->sc_regs->fmpvcr |= FMPVCR_VPP;
228: else
229: sc->sc_regs->fmpvcr &= ~FMPVCR_VPP;
230:
231: c = ((*ptr) & SCF_FMCTRL_SELADDR) >> 3;
232: sc->sc_regs->fmpcr1 =
233: (sc->sc_regs->fmpcr1 & ~FMPCR1_SELADDR) | (c << 1);
234:
235: break;
236: case SCFIOCGFMCTRL:
237: c = (sc->sc_regs->fmpcr1 & FMPCR1_SELADDR) << 2;
238: if (sc->sc_regs->fmpcr1 & FMPCR1_SELROM)
239: c |= SCF_FMCTRL_SELROM;
240: if (sc->sc_regs->fmpcr2 & FMPCR2_SELBOOT)
241: c |= SCF_FMCTRL_SELBOOT;
242: if (sc->sc_regs->fmpvcr & FMPVCR_VPP)
243: c |= SCF_FMCTRL_WRITEV;
244: *ptr = c;
245: break;
246: default:
247: error = ENOTTY;
248: }
249:
250: return (error);
251: }
252:
253: void
254: scfblink(v)
255: void *v;
256: {
257: struct scf_softc *sc;
258: int s, avg, hi = 0;
259:
260: if (scf_cd.cd_ndevs == 0)
261: return;
262:
263: sc = scf_cd.cd_devs[0];
264: if (sc == NULL)
265: return;
266:
267: if (sparc_led_blink == 0) {
268: sc->sc_regs->led1 &= ~LED_MASK;
269: sc->sc_regs->led2 &= ~LED_MASK;
270: sc->sc_regs->ssldcr = 0;
271: return;
272: }
273:
274: avg = averunnable.ldavg[0] >> FSHIFT;
275: while (avg > 15) {
276: hi = 1;
277: avg >>= 4;
278: }
279:
280: s = splhigh();
281: if (sc->sc_tick & 1) {
282: sc->sc_regs->led1 &= ~LED_MASK;
283: sc->sc_regs->led2 |= LED_COLOR_GREEN;
284: }
285: else {
286: sc->sc_regs->led1 |= LED_COLOR_YELLOW;
287: sc->sc_regs->led2 &= ~LED_MASK;
288: }
289: sc->sc_regs->ssldcr = scf_pattern[avg] | (hi ? SSLDCR_P : 0);
290: splx(s);
291:
292: sc->sc_tick++;
293:
294: s = ((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1);
295: timeout_add(&sc->sc_blink_tmo, s);
296: }
CVSweb