cy_pci.c revision 1.1
1/*	$NetBSD: cy_pci.c,v 1.1 1996/09/24 17:59:33 christos Exp $	*/
2
3/*
4 * cy_pci.c
5 *
6 * Driver for Cyclades Cyclom-8/16/32 multiport serial cards
7 * (currently not tested with Cyclom-32 cards)
8 *
9 * Timo Rossi, 1996
10 *
11 */
12#include <sys/param.h>
13#include <sys/systm.h>
14#include <sys/device.h>
15
16#include <machine/bus.h>
17#include <machine/intr.h>
18
19#include <dev/pci/pcivar.h>
20#include <dev/pci/pcireg.h>
21#include <dev/pci/pcidevs.h>
22
23#include <dev/ic/cd1400reg.h>
24#include <dev/ic/cyreg.h>
25#include <dev/ic/cyvar.h>
26
27static int cy_probe_pci __P((struct device *, void *, void *));
28static void cy_attach_pci  __P((struct device *, struct device *, void *));
29static int cy_map_pci __P((struct pci_attach_args *, struct cy_softc *,
30    bus_io_handle_t *, bus_mem_size_t  *, bus_io_size_t *));
31static void cy_unmap_pci __P((struct cy_softc *, bus_io_handle_t,
32    bus_mem_size_t, bus_io_size_t));
33
34struct cfattach cy_pci_ca = {
35	sizeof(struct cy_softc), cy_probe_pci, cy_attach_pci
36};
37
38static int
39cy_map_pci(pa, sc, ioh, iosize, memsize)
40	struct pci_attach_args *pa;
41	struct cy_softc *sc;
42	bus_io_handle_t *ioh;
43	bus_mem_size_t  *memsize;
44	bus_io_size_t *iosize;
45{
46	bus_io_addr_t iobase;
47	bus_mem_addr_t  memaddr;
48	int cacheable;
49
50	if (pci_mem_find(pa->pa_pc, pa->pa_tag, 0x18, &memaddr, memsize,
51	    &cacheable) != 0) {
52		printf("%s: can't find PCI card memory", sc->sc_dev.dv_xname);
53		return 0;
54	}
55	/* map the memory (non-cacheable) */
56	if (bus_mem_map(sc->sc_bc, memaddr, *memsize, 0, &sc->sc_memh) != 0) {
57		printf("%s: couldn't map PCI memory region\n",
58		    sc->sc_dev.dv_xname);
59		return 0;
60	}
61	/* the PCI Cyclom IO space is only used for enabling interrupts */
62	if (pci_io_find(pa->pa_pc, pa->pa_tag, 0x14, &iobase, iosize) != 0) {
63		printf("%s: couldn't find PCI io region\n",
64		    sc->sc_dev.dv_xname);
65		goto unmapmem;
66	}
67	if (bus_io_map(sc->sc_bc, iobase, *iosize, ioh) != 0) {
68		printf("%s: couldn't map PCI io region\n", sc->sc_dev.dv_xname);
69		goto unmapmem;
70	}
71	return 1;
72
73unmapio:
74	bus_io_unmap(sc->sc_bc, *ioh, *iosize);
75unmapmem:
76	bus_mem_unmap(sc->sc_bc, sc->sc_memh, *memsize);
77	return 0;
78}
79
80static void
81cy_unmap_pci(sc, ioh, iosize, memsize)
82	struct cy_softc *sc;
83	bus_io_handle_t ioh;
84	bus_io_size_t iosize;
85	bus_mem_size_t  memsize;
86
87{
88	bus_io_unmap(sc->sc_bc, ioh, iosize);
89	bus_mem_unmap(sc->sc_bc, sc->sc_memh, memsize);
90}
91
92static int
93cy_probe_pci(parent, match, aux)
94	struct device  *parent;
95	void           *match, *aux;
96{
97	vm_offset_t v_addr, p_addr;
98	struct pci_attach_args *pa = aux;
99	bus_io_handle_t ioh;
100	bus_mem_size_t  memsize;
101	bus_io_size_t iosize;
102	int rv = 0;
103	struct cy_softc sc;
104
105	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CYCLADES)
106		return 0;
107
108	switch (PCI_PRODUCT(pa->pa_id)) {
109	case PCI_PRODUCT_CYCLADES_CYCLOMY_1:
110		break;
111	case PCI_PRODUCT_CYCLADES_CYCLOMY_2:
112		break;
113	default:
114		return 0;
115	}
116
117#ifdef CY_DEBUG
118	printf("cy: Found Cyclades PCI device, id = 0x%x\n", pa->pa_id);
119#endif
120	memcpy(&sc.sc_dev, match, sizeof(struct device));
121
122	sc.sc_bc = pa->pa_bc;
123	sc.sc_bustype = CY_BUSTYPE_PCI;
124
125	if (cy_map_pci(pa, &sc, &ioh, &iosize, &memsize) == 0)
126		return 0;
127
128#ifdef CY_DEBUG
129	printf("%s: pci mapped mem 0x%lx (size %d), io 0x%x (size %d)\n",
130	    sc.sc_dev.dv_xname, memaddr, memsize, iobase, iosize);
131#endif
132
133	if ((rv = cy_find(&sc)) == 0)
134		printf("%s: PCI Cyclom card with no CD1400s!?\n",
135		    sc.sc_dev.dv_xname);
136
137	cy_unmap_pci(&sc, ioh, iosize, memsize);
138	return rv;
139}
140
141
142static void
143cy_attach_pci(parent, self, aux)
144	struct device  *parent, *self;
145	void *aux;
146{
147	struct cy_softc *sc = (void *) self;
148	pci_intr_handle_t intrhandle;
149	bus_io_handle_t ioh;
150	bus_mem_size_t  memsize;
151	bus_io_size_t iosize;
152	struct pci_attach_args *pa = aux;
153
154	sc->sc_bc = pa->pa_bc;
155	sc->sc_bustype = CY_BUSTYPE_PCI;
156
157	if (cy_map_pci(pa, sc, &ioh, &iosize, &memsize) == 0)
158		panic("%s: mapping failed", sc->sc_dev.dv_xname);
159
160	if (cy_find(sc) == 0)
161		panic("%s: Cannot find card", sc->sc_dev.dv_xname);
162
163	cy_attach(parent, self, aux);
164
165	/* Enable PCI card interrupts */
166	bus_io_write_2(sc->sc_bc, ioh, CY_PCI_INTENA,
167	    bus_io_read_2(sc->sc_bc, ioh, CY_PCI_INTENA) | 0x900);
168
169	if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
170	    pa->pa_intrline, &intrhandle) != 0)
171		panic("%s: couldn't map PCI interrupt", sc->sc_dev.dv_xname);
172
173
174	sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle,
175	    IPL_TTY, cy_intr, sc);
176
177	if (sc->sc_ih == NULL)
178		panic("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
179}
180