sio.c revision 1.14 1 /* $NetBSD: sio.c,v 1.14 1996/11/25 03:15:24 cgd Exp $ */
2
3 /*
4 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
5 * All rights reserved.
6 *
7 * Author: Chris G. Demetriou
8 *
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/device.h>
34
35 #include <machine/intr.h>
36 #include <machine/bus.h>
37
38 #include <dev/isa/isavar.h>
39 #include <dev/eisa/eisavar.h>
40
41 #include <dev/pci/pcireg.h>
42 #include <dev/pci/pcivar.h>
43 #include <dev/pci/pcidevs.h>
44
45 #include <alpha/pci/siovar.h>
46
47 struct sio_softc {
48 struct device sc_dv;
49
50 bus_space_tag_t sc_iot, sc_memt;
51 int sc_haseisa;
52 };
53
54 int siomatch __P((struct device *, void *, void *));
55 void sioattach __P((struct device *, struct device *, void *));
56
57 struct cfattach sio_ca = {
58 sizeof(struct sio_softc), siomatch, sioattach,
59 };
60
61 struct cfdriver sio_cd = {
62 NULL, "sio", DV_DULL,
63 };
64
65 int pcebmatch __P((struct device *, void *, void *));
66
67 struct cfattach pceb_ca = {
68 sizeof(struct device), pcebmatch, sioattach,
69 };
70
71 struct cfdriver pceb_cd = {
72 NULL, "pceb", DV_DULL,
73 };
74
75 union sio_attach_args {
76 const char *sa_name; /* XXX should be common */
77 struct isabus_attach_args sa_iba;
78 struct eisabus_attach_args sa_eba;
79 };
80
81 int sioprint __P((void *, const char *pnp));
82 void sio_isa_attach_hook __P((struct device *, struct device *,
83 struct isabus_attach_args *));
84 void sio_eisa_attach_hook __P((struct device *, struct device *,
85 struct eisabus_attach_args *));
86 int sio_eisa_maxslots __P((void *));
87 int sio_eisa_intr_map __P((void *, u_int, eisa_intr_handle_t *));
88
89 void sio_bridge_callback __P((void *));
90
91 int
92 siomatch(parent, match, aux)
93 struct device *parent;
94 void *match, *aux;
95 {
96 struct pci_attach_args *pa = aux;
97
98 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL ||
99 PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_SIO)
100 return (0);
101
102 return (1);
103 }
104
105 int
106 pcebmatch(parent, match, aux)
107 struct device *parent;
108 void *match, *aux;
109 {
110 struct pci_attach_args *pa = aux;
111
112 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL ||
113 PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_PCEB)
114 return (0);
115
116 return (1);
117 }
118
119 void
120 sioattach(parent, self, aux)
121 struct device *parent, *self;
122 void *aux;
123 {
124 struct sio_softc *sc = (struct sio_softc *)self;
125 struct pci_attach_args *pa = aux;
126 char devinfo[256];
127
128 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo);
129 printf(": %s (rev. 0x%02x)\n", devinfo,
130 PCI_REVISION(pa->pa_class));
131
132 sc->sc_iot = pa->pa_iot;
133 sc->sc_memt = pa->pa_memt;
134 sc->sc_haseisa = (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PCEB);
135
136 #ifdef EVCNT_COUNTERS
137 evcnt_attach(&sc->sc_dv, "intr", &sio_intr_evcnt);
138 #endif
139
140 set_pci_isa_bridge_callback(sio_bridge_callback, sc);
141 }
142
143 void
144 sio_bridge_callback(v)
145 void *v;
146 {
147 struct sio_softc *sc = v;
148 struct alpha_eisa_chipset ec;
149 struct alpha_isa_chipset ic;
150 union sio_attach_args sa;
151
152 if (sc->sc_haseisa) {
153 ec.ec_v = NULL;
154 ec.ec_attach_hook = sio_eisa_attach_hook;
155 ec.ec_maxslots = sio_eisa_maxslots;
156 ec.ec_intr_map = sio_eisa_intr_map;
157 ec.ec_intr_string = sio_intr_string;
158 ec.ec_intr_establish = sio_intr_establish;
159 ec.ec_intr_disestablish = sio_intr_disestablish;
160
161 sa.sa_eba.eba_busname = "eisa";
162 sa.sa_eba.eba_iot = sc->sc_iot;
163 sa.sa_eba.eba_memt = sc->sc_memt;
164 sa.sa_eba.eba_ec = &ec;
165 config_found(&sc->sc_dv, &sa.sa_eba, sioprint);
166 }
167
168 ic.ic_v = NULL;
169 ic.ic_attach_hook = sio_isa_attach_hook;
170 ic.ic_intr_establish = sio_intr_establish;
171 ic.ic_intr_disestablish = sio_intr_disestablish;
172
173 sa.sa_iba.iba_busname = "isa";
174 sa.sa_iba.iba_iot = sc->sc_iot;
175 sa.sa_iba.iba_memt = sc->sc_memt;
176 sa.sa_iba.iba_ic = ⁣
177 config_found(&sc->sc_dv, &sa.sa_iba, sioprint);
178 }
179
180 int
181 sioprint(aux, pnp)
182 void *aux;
183 const char *pnp;
184 {
185 register union sio_attach_args *sa = aux;
186
187 if (pnp)
188 printf("%s at %s", sa->sa_name, pnp);
189 return (UNCONF);
190 }
191
192 void
193 sio_isa_attach_hook(parent, self, iba)
194 struct device *parent, *self;
195 struct isabus_attach_args *iba;
196 {
197
198 /* Nothing to do. */
199 }
200
201 void
202 sio_eisa_attach_hook(parent, self, eba)
203 struct device *parent, *self;
204 struct eisabus_attach_args *eba;
205 {
206
207 /* Nothing to do. */
208 }
209
210 int
211 sio_eisa_maxslots(v)
212 void *v;
213 {
214
215 return 16; /* as good a number as any. only 8, maybe? */
216 }
217
218 int
219 sio_eisa_intr_map(v, irq, ihp)
220 void *v;
221 u_int irq;
222 eisa_intr_handle_t *ihp;
223 {
224
225 #define ICU_LEN 16 /* number of ISA IRQs (XXX) */
226
227 if (irq >= ICU_LEN) {
228 printf("sio_eisa_intr_map: bad IRQ %d\n", irq);
229 *ihp = -1;
230 return 1;
231 }
232 if (irq == 2) {
233 printf("sio_eisa_intr_map: changed IRQ 2 to IRQ 9\n");
234 irq = 9;
235 }
236
237 *ihp = irq;
238 return 0;
239 }
240