1*6aef9a4eSmpi /* $OpenBSD: sio.c,v 1.41 2022/03/13 08:04:13 mpi Exp $ */
23a630e3fSniklas /* $NetBSD: sio.c,v 1.15 1996/12/05 01:39:36 cgd Exp $ */
3df930be7Sderaadt
4df930be7Sderaadt /*
5417eba8cSderaadt * Copyright (c) 1995, 1996 Carnegie-Mellon University.
6df930be7Sderaadt * All rights reserved.
7df930be7Sderaadt *
8df930be7Sderaadt * Author: Chris G. Demetriou
9df930be7Sderaadt *
10df930be7Sderaadt * Permission to use, copy, modify and distribute this software and
11df930be7Sderaadt * its documentation is hereby granted, provided that both the copyright
12df930be7Sderaadt * notice and this permission notice appear in all copies of the
13df930be7Sderaadt * software, derivative works or modified versions, and any portions
14df930be7Sderaadt * thereof, and that both notices appear in supporting documentation.
15df930be7Sderaadt *
16df930be7Sderaadt * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17df930be7Sderaadt * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18df930be7Sderaadt * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19df930be7Sderaadt *
20df930be7Sderaadt * Carnegie Mellon requests users of this software to return to
21df930be7Sderaadt *
22df930be7Sderaadt * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23df930be7Sderaadt * School of Computer Science
24df930be7Sderaadt * Carnegie Mellon University
25df930be7Sderaadt * Pittsburgh PA 15213-3890
26df930be7Sderaadt *
27df930be7Sderaadt * any improvements or extensions that they make and grant Carnegie the
28df930be7Sderaadt * rights to redistribute these changes.
29df930be7Sderaadt */
30df930be7Sderaadt
31df930be7Sderaadt #include <sys/param.h>
32df930be7Sderaadt #include <sys/systm.h>
33df930be7Sderaadt #include <sys/kernel.h>
34df930be7Sderaadt #include <sys/device.h>
35df930be7Sderaadt
36417eba8cSderaadt #include <machine/intr.h>
37e464495eSniklas #include <machine/bus.h>
38417eba8cSderaadt
3934fbf6deSderaadt #include <dev/isa/isavar.h>
4034fbf6deSderaadt #include <dev/eisa/eisavar.h>
4134fbf6deSderaadt
42df930be7Sderaadt #include <dev/pci/pcireg.h>
43df930be7Sderaadt #include <dev/pci/pcivar.h>
44df930be7Sderaadt #include <dev/pci/pcidevs.h>
45df930be7Sderaadt
4634fbf6deSderaadt #include <alpha/pci/siovar.h>
47df930be7Sderaadt
4822e73efaSmiod #include "eisa.h"
4933ba0896Sart #include "isadma.h"
5033ba0896Sart
513a630e3fSniklas struct sio_softc {
523a630e3fSniklas struct device sc_dv;
533a630e3fSniklas
543a630e3fSniklas bus_space_tag_t sc_iot, sc_memt;
55d1688987Snate bus_dma_tag_t sc_dmat;
563a630e3fSniklas int sc_haseisa;
570087ab59Smiod
580087ab59Smiod struct alpha_eisa_chipset sc_ec;
590087ab59Smiod struct alpha_isa_chipset sc_ic;
603a630e3fSniklas };
613a630e3fSniklas
62c4071fd1Smillert int siomatch(struct device *, void *, void *);
63c4071fd1Smillert void sioattach(struct device *, struct device *, void *);
64acd48a0eSmiod int sioactivate(struct device *, int);
65df930be7Sderaadt
66578428abSmiod extern int sio_intr_alloc(isa_chipset_tag_t, int, int, int *);
67578428abSmiod extern int sio_intr_check(isa_chipset_tag_t, int, int);
68d1688987Snate
690087ab59Smiod const struct cfattach sio_ca = {
70acd48a0eSmiod .ca_devsize = sizeof(struct sio_softc),
71acd48a0eSmiod .ca_match = siomatch,
72acd48a0eSmiod .ca_attach = sioattach,
73acd48a0eSmiod .ca_activate = sioactivate
74417eba8cSderaadt };
75417eba8cSderaadt
76417eba8cSderaadt struct cfdriver sio_cd = {
77417eba8cSderaadt NULL, "sio", DV_DULL,
78df930be7Sderaadt };
79df930be7Sderaadt
80c4071fd1Smillert int pcebmatch(struct device *, void *, void *);
8134fbf6deSderaadt
82*6aef9a4eSmpi const struct cfattach pceb_ca = {
83835a491cSart sizeof(struct sio_softc), pcebmatch, sioattach,
8434fbf6deSderaadt };
8534fbf6deSderaadt
86417eba8cSderaadt struct cfdriver pceb_cd = {
87417eba8cSderaadt NULL, "pceb", DV_DULL,
88417eba8cSderaadt };
89417eba8cSderaadt
90417eba8cSderaadt union sio_attach_args {
91417eba8cSderaadt const char *sa_name; /* XXX should be common */
92417eba8cSderaadt struct isabus_attach_args sa_iba;
93417eba8cSderaadt struct eisabus_attach_args sa_eba;
94417eba8cSderaadt };
95417eba8cSderaadt
96c4071fd1Smillert int sioprint(void *, const char *pnp);
97c4071fd1Smillert void sio_isa_attach_hook(struct device *, struct device *,
98c4071fd1Smillert struct isabus_attach_args *);
99c4071fd1Smillert void sio_eisa_attach_hook(struct device *, struct device *,
100c4071fd1Smillert struct eisabus_attach_args *);
101c4071fd1Smillert int sio_eisa_intr_map(void *, u_int, eisa_intr_handle_t *);
102712c6871Sbrad void sio_bridge_callback(struct device *);
1033a630e3fSniklas
104df930be7Sderaadt int
siomatch(parent,match,aux)105df930be7Sderaadt siomatch(parent, match, aux)
106df930be7Sderaadt struct device *parent;
1073a630e3fSniklas void *match;
1083a630e3fSniklas void *aux;
109df930be7Sderaadt {
110417eba8cSderaadt struct pci_attach_args *pa = aux;
111df930be7Sderaadt
1126a30a1c1Smillert if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CONTAQ &&
113e6dd45c8Smillert PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CONTAQ_82C693 &&
1146a30a1c1Smillert pa->pa_function == 0)
11534fbf6deSderaadt return (1);
1166a30a1c1Smillert
1176a30a1c1Smillert if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
1186a30a1c1Smillert PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_SIO)
1196a30a1c1Smillert return (1);
1206a30a1c1Smillert
121e9c60ed0Sericj if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALI &&
122fcb50aabSderaadt PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALI_M1533)
123fcb50aabSderaadt return(1);
124fcb50aabSderaadt
125fcb50aabSderaadt if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALI &&
126e9c60ed0Sericj PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALI_M1543)
127e9c60ed0Sericj return(1);
1286a30a1c1Smillert return (0);
12934fbf6deSderaadt }
13034fbf6deSderaadt
13134fbf6deSderaadt int
pcebmatch(parent,match,aux)13234fbf6deSderaadt pcebmatch(parent, match, aux)
13334fbf6deSderaadt struct device *parent;
1343a630e3fSniklas void *match;
1353a630e3fSniklas void *aux;
13634fbf6deSderaadt {
137417eba8cSderaadt struct pci_attach_args *pa = aux;
13834fbf6deSderaadt
1394887a701Sart if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
1404887a701Sart PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PCEB)
141df930be7Sderaadt return (1);
1424887a701Sart
1434887a701Sart return (0);
144df930be7Sderaadt }
145df930be7Sderaadt
146df930be7Sderaadt void
sioattach(parent,self,aux)147df930be7Sderaadt sioattach(parent, self, aux)
148df930be7Sderaadt struct device *parent, *self;
149df930be7Sderaadt void *aux;
150df930be7Sderaadt {
1513a630e3fSniklas struct sio_softc *sc = (struct sio_softc *)self;
152417eba8cSderaadt struct pci_attach_args *pa = aux;
153df930be7Sderaadt
15450c9667dSderaadt printf("\n");
15534fbf6deSderaadt
1563a630e3fSniklas sc->sc_iot = pa->pa_iot;
1573a630e3fSniklas sc->sc_memt = pa->pa_memt;
158d1688987Snate sc->sc_dmat = pa->pa_dmat;
1595d7756c0Sart sc->sc_haseisa = (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
160f87980b9Sart PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PCEB);
161df930be7Sderaadt
162712c6871Sbrad config_defer(self, sio_bridge_callback);
1633a630e3fSniklas }
1643a630e3fSniklas
165acd48a0eSmiod int
sioactivate(struct device * self,int act)166acd48a0eSmiod sioactivate(struct device *self, int act)
167acd48a0eSmiod {
168acd48a0eSmiod int rv = 0;
169acd48a0eSmiod
170acd48a0eSmiod switch (act) {
171acd48a0eSmiod case DVACT_POWERDOWN:
172acd48a0eSmiod rv = config_activate_children(self, act);
173acd48a0eSmiod sio_intr_shutdown();
174acd48a0eSmiod break;
175acd48a0eSmiod default:
176acd48a0eSmiod rv = config_activate_children(self, act);
177acd48a0eSmiod break;
178acd48a0eSmiod }
179acd48a0eSmiod return (rv);
180acd48a0eSmiod }
181acd48a0eSmiod
1823a630e3fSniklas void
sio_bridge_callback(self)183712c6871Sbrad sio_bridge_callback(self)
184712c6871Sbrad struct device *self;
1853a630e3fSniklas {
186712c6871Sbrad struct sio_softc *sc = (struct sio_softc *)self;
1873a630e3fSniklas union sio_attach_args sa;
1883a630e3fSniklas
1893a630e3fSniklas if (sc->sc_haseisa) {
1900087ab59Smiod sc->sc_ec.ec_v = NULL;
1910087ab59Smiod sc->sc_ec.ec_maxslots = 0; /* will be filled by attach_hook */
1920087ab59Smiod sc->sc_ec.ec_attach_hook = sio_eisa_attach_hook;
1930087ab59Smiod sc->sc_ec.ec_intr_map = sio_eisa_intr_map;
1940087ab59Smiod sc->sc_ec.ec_intr_string = sio_intr_string;
1950087ab59Smiod sc->sc_ec.ec_intr_establish = sio_intr_establish;
1960087ab59Smiod sc->sc_ec.ec_intr_disestablish = sio_intr_disestablish;
197417eba8cSderaadt
198417eba8cSderaadt sa.sa_eba.eba_busname = "eisa";
1993a630e3fSniklas sa.sa_eba.eba_iot = sc->sc_iot;
2003a630e3fSniklas sa.sa_eba.eba_memt = sc->sc_memt;
2013b17992dSmiod sa.sa_eba.eba_dmat =
2023b17992dSmiod alphabus_dma_get_tag(sc->sc_dmat, ALPHA_BUS_EISA);
2030087ab59Smiod sa.sa_eba.eba_ec = &sc->sc_ec;
2043a630e3fSniklas config_found(&sc->sc_dv, &sa.sa_eba, sioprint);
205df930be7Sderaadt }
206df930be7Sderaadt
2070087ab59Smiod sc->sc_ic.ic_v = NULL;
2080087ab59Smiod sc->sc_ic.ic_attach_hook = sio_isa_attach_hook;
2090087ab59Smiod sc->sc_ic.ic_intr_establish = sio_intr_establish;
2100087ab59Smiod sc->sc_ic.ic_intr_disestablish = sio_intr_disestablish;
2110087ab59Smiod sc->sc_ic.ic_intr_alloc = sio_intr_alloc;
2120087ab59Smiod sc->sc_ic.ic_intr_check = sio_intr_check;
213417eba8cSderaadt
214417eba8cSderaadt sa.sa_iba.iba_busname = "isa";
2153a630e3fSniklas sa.sa_iba.iba_iot = sc->sc_iot;
2163a630e3fSniklas sa.sa_iba.iba_memt = sc->sc_memt;
21733ba0896Sart #if NISADMA > 0
218d1688987Snate sa.sa_iba.iba_dmat =
219d1688987Snate alphabus_dma_get_tag(sc->sc_dmat, ALPHA_BUS_ISA);
22033ba0896Sart #endif
2210087ab59Smiod sa.sa_iba.iba_ic = &sc->sc_ic;
2223a630e3fSniklas config_found(&sc->sc_dv, &sa.sa_iba, sioprint);
223417eba8cSderaadt }
224417eba8cSderaadt
225417eba8cSderaadt int
sioprint(aux,pnp)226df930be7Sderaadt sioprint(aux, pnp)
227df930be7Sderaadt void *aux;
228833613b2Skstailey const char *pnp;
229df930be7Sderaadt {
230417eba8cSderaadt register union sio_attach_args *sa = aux;
231df930be7Sderaadt
232df930be7Sderaadt if (pnp)
233417eba8cSderaadt printf("%s at %s", sa->sa_name, pnp);
234df930be7Sderaadt return (UNCONF);
235df930be7Sderaadt }
236417eba8cSderaadt
237417eba8cSderaadt void
sio_isa_attach_hook(parent,self,iba)238417eba8cSderaadt sio_isa_attach_hook(parent, self, iba)
239417eba8cSderaadt struct device *parent, *self;
240417eba8cSderaadt struct isabus_attach_args *iba;
241417eba8cSderaadt {
2429cf4a814Sart /* Nothing to do. */
243417eba8cSderaadt }
244417eba8cSderaadt
245417eba8cSderaadt void
sio_eisa_attach_hook(parent,self,eba)246417eba8cSderaadt sio_eisa_attach_hook(parent, self, eba)
247417eba8cSderaadt struct device *parent, *self;
248417eba8cSderaadt struct eisabus_attach_args *eba;
249417eba8cSderaadt {
25022e73efaSmiod #if NEISA > 0
25122e73efaSmiod eisa_init(eba->eba_ec);
25222e73efaSmiod #endif
253417eba8cSderaadt }
254417eba8cSderaadt
255417eba8cSderaadt int
sio_eisa_intr_map(v,irq,ihp)256417eba8cSderaadt sio_eisa_intr_map(v, irq, ihp)
257417eba8cSderaadt void *v;
258417eba8cSderaadt u_int irq;
259417eba8cSderaadt eisa_intr_handle_t *ihp;
260417eba8cSderaadt {
261417eba8cSderaadt
262417eba8cSderaadt #define ICU_LEN 16 /* number of ISA IRQs (XXX) */
263417eba8cSderaadt
264417eba8cSderaadt if (irq >= ICU_LEN) {
265417eba8cSderaadt printf("sio_eisa_intr_map: bad IRQ %d\n", irq);
266417eba8cSderaadt *ihp = -1;
267417eba8cSderaadt return 1;
268417eba8cSderaadt }
269417eba8cSderaadt if (irq == 2) {
270417eba8cSderaadt printf("sio_eisa_intr_map: changed IRQ 2 to IRQ 9\n");
271417eba8cSderaadt irq = 9;
272417eba8cSderaadt }
273417eba8cSderaadt
274417eba8cSderaadt *ihp = irq;
275417eba8cSderaadt return 0;
276417eba8cSderaadt }
277