digi_pci.c revision 76853
1105197Ssam/*-
2105197Ssam * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
3139823Simp *   based on work by Slawa Olhovchenkov
4105197Ssam *                    John Prince <johnp@knight-trosoft.com>
5105197Ssam *                    Eric Hernes
6105197Ssam * All rights reserved.
7105197Ssam *
8105197Ssam * Redistribution and use in source and binary forms, with or without
9105197Ssam * modification, are permitted provided that the following conditions
10105197Ssam * are met:
11105197Ssam * 1. Redistributions of source code must retain the above copyright
12105197Ssam *    notice, this list of conditions and the following disclaimer.
13105197Ssam * 2. Redistributions in binary form must reproduce the above copyright
14105197Ssam *    notice, this list of conditions and the following disclaimer in the
15105197Ssam *    documentation and/or other materials provided with the distribution.
16105197Ssam *
17105197Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18105197Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19105197Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20105197Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21105197Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22105197Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23105197Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24105197Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25105197Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26105197Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27105197Ssam * SUCH DAMAGE.
28105197Ssam *
29105197Ssam * $FreeBSD: head/sys/dev/digi/digi_pci.c 76853 2001-05-19 17:06:48Z brian $
30105197Ssam */
31105197Ssam
32105197Ssam#include <sys/param.h>
33105197Ssam
34105197Ssam#include <sys/systm.h>
35105197Ssam#include <sys/kernel.h>
36105197Ssam#include <sys/tty.h>
37105197Ssam#include <sys/bus.h>
38105197Ssam#include <machine/bus.h>
39105197Ssam#include <sys/rman.h>
40105197Ssam#include <machine/resource.h>
41105197Ssam#include <vm/vm.h>
42105197Ssam#include <vm/pmap.h>
43105197Ssam#include <pci/pcivar.h>
44105197Ssam
45105197Ssam#include <sys/digiio.h>
46105197Ssam#include <dev/digi/digireg.h>
47105197Ssam#include <dev/digi/digi.h>
48105197Ssam#include <dev/digi/digi_pci.h>
49105197Ssam
50105197Ssamstatic u_char *
51195699Srwatsondigi_pci_setwin(struct digi_softc *sc, unsigned int addr)
52105197Ssam{
53105197Ssam	return (sc->vmem + addr);
54105197Ssam}
55105197Ssam
56105197Ssamstatic void
57105197Ssamdigi_pci_hidewin(struct digi_softc *sc)
58105197Ssam{
59105197Ssam	return;
60105197Ssam}
61105197Ssam
62105197Ssamstatic void
63105197Ssamdigi_pci_towin(struct digi_softc *sc, int win)
64105197Ssam{
65105197Ssam	return;
66105197Ssam}
67105197Ssam
68105197Ssamstatic int
69105197Ssamdigi_pci_probe(device_t dev)
70105197Ssam{
71105197Ssam	unsigned int device_id = pci_get_devid(dev);
72105197Ssam
73105197Ssam	if (device_get_unit(dev) >= 16) {
74105197Ssam		/* Don't overflow our control mask */
75105197Ssam		device_printf(dev, "At most 16 digiboards may be used\n");
76105197Ssam		return (ENXIO);
77105197Ssam	}
78105197Ssam
79195699Srwatson	if ((device_id & 0xffff) != PCI_VENDOR_DIGI)
80195699Srwatson		return (ENXIO);
81105197Ssam
82105197Ssam	switch (device_id >> 16) {
83195699Srwatson	case PCI_DEVICE_EPC:
84195699Srwatson	case PCI_DEVICE_XEM:
85195699Srwatson	case PCI_DEVICE_XR:
86195699Srwatson	case PCI_DEVICE_CX:
87105197Ssam	case PCI_DEVICE_XRJ:
88215701Sdim	case PCI_DEVICE_EPCJ:
89195727Srwatson	case PCI_DEVICE_920_4:
90195699Srwatson	case PCI_DEVICE_920_8:
91105197Ssam	case PCI_DEVICE_920_2:
92105197Ssam		return (0);
93105197Ssam	}
94105197Ssam
95105197Ssam	return (ENXIO);
96105197Ssam}
97105197Ssam
98105197Ssamstatic int
99105197Ssamdigi_pci_attach(device_t dev)
100105197Ssam{
101105197Ssam	struct digi_softc *sc;
102105197Ssam	u_int32_t device_id;
103105197Ssam#ifdef DIGI_INTERRUPT
104105197Ssam	int retVal = 0;
105105197Ssam#endif
106105197Ssam
107105197Ssam	sc = device_get_softc(dev);
108105197Ssam	KASSERT(sc, ("digi%d: softc not allocated in digi_pci_attach\n",
109105197Ssam	    device_get_unit(dev)));
110105197Ssam
111105197Ssam	bzero(sc, sizeof(*sc));
112105197Ssam	sc->dev = dev;
113105197Ssam	sc->res.unit = device_get_unit(dev);
114105197Ssam
115105197Ssam	device_id = pci_get_devid(dev);
116105197Ssam	switch (device_id >> 16) {
117105197Ssam	case PCI_DEVICE_EPC:
118169425Sgnn		sc->name = "Digiboard PCI EPC/X ASIC";
119169425Sgnn		sc->res.mrid = 0x10;
120105197Ssam		sc->model = PCIEPCX;
121105197Ssam		sc->module = "EPCX_PCI";
122105197Ssam		break;
123105197Ssam	case PCI_DEVICE_XEM:
124105197Ssam		sc->name = "Digiboard PCI PC/Xem ASIC";
125105197Ssam		sc->res.mrid = 0x10;
126105197Ssam		sc->model = PCXEM;
127105197Ssam		sc->module = "Xem";
128105197Ssam		break;
129105197Ssam	case PCI_DEVICE_XR:
130105197Ssam		sc->name = "Digiboard PCI PC/Xr ASIC";
131120585Ssam		sc->res.mrid = 0x10;
132120585Ssam		sc->model = PCIXR;
133105197Ssam		sc->module = "Xr";
134105197Ssam		break;
135105197Ssam	case PCI_DEVICE_CX:
136105197Ssam		sc->name = "Digiboard PCI C/X ASIC";
137105197Ssam		sc->res.mrid = 0x10;
138105197Ssam		sc->model = PCCX;
139105197Ssam		sc->module = "CX_PCI";
140105197Ssam		break;
141105197Ssam	case PCI_DEVICE_XRJ:
142105197Ssam		sc->name = "Digiboard PCI PC/Xr PLX";
143105197Ssam		sc->res.mrid = 0x18;
144105197Ssam		sc->model = PCIXR;
145105197Ssam		sc->module = "Xr";
146105197Ssam		break;
147105197Ssam	case PCI_DEVICE_EPCJ:
148105197Ssam		sc->name = "Digiboard PCI EPC/X PLX";
149105197Ssam		sc->res.mrid = 0x18;
150181803Sbz		sc->model = PCIEPCX;
151105197Ssam		sc->module = "EPCX_PCI";
152105197Ssam		break;
153105197Ssam	case PCI_DEVICE_920_4:			/* Digi PCI4r 920 */
154105197Ssam		sc->name = "Digiboard PCI4r 920";
155105197Ssam		sc->res.mrid = 0x10;
156105197Ssam		sc->model = PCIXR;
157105197Ssam		sc->module = "Xr";
158105197Ssam		break;
159105197Ssam	case PCI_DEVICE_920_8:			/* Digi PCI8r 920 */
160105197Ssam		sc->name = "Digiboard PCI8r 920";
161105197Ssam		sc->res.mrid = 0x10;
162105197Ssam		sc->model = PCIXR;
163105197Ssam		sc->module = "Xr";
164105197Ssam		break;
165105197Ssam	case PCI_DEVICE_920_2:			/* Digi PCI2r 920 */
166105197Ssam		sc->name = "Digiboard PCI2r 920";
167105197Ssam		sc->res.mrid = 0x10;
168120585Ssam		sc->model = PCIXR;
169120585Ssam		sc->module = "Xr";
170105197Ssam		break;
171105197Ssam	default:
172105197Ssam		device_printf(dev, "Unknown device id = %08x\n", device_id);
173120585Ssam		return (ENXIO);
174120585Ssam	}
175105197Ssam
176105197Ssam	pci_write_config(dev, 0x40, 0, 4);
177105197Ssam	pci_write_config(dev, 0x46, 0, 4);
178120585Ssam
179120585Ssam	sc->res.mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->res.mrid,
180105197Ssam	    0, ~0, 1, RF_ACTIVE);
181105197Ssam
182105197Ssam#ifdef DIGI_INTERRUPT
183105197Ssam	sc->res.irqrid = 0;
184120585Ssam	sc->res.irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->res.irqrid,
185120585Ssam	    0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
186105197Ssam	if (sc->res.irq == NULL) {
187105197Ssam		device_printf(dev, "couldn't map interrupt\n");
188105197Ssam		return (ENXIO);
189105197Ssam	}
190105197Ssam	retVal = bus_setup_intr(dev, sc->res.irq, INTR_TYPE_TTY,
191105197Ssam	    digiintr, sc, &sc->res.irqHandler);
192105197Ssam#else
193105197Ssam	DLOG(DIGIDB_IRQ, (sc->dev, "Interrupt support compiled out\n"));
194105197Ssam#endif
195105197Ssam
196105197Ssam	sc->vmem = rman_get_virtual(sc->res.mem);
197105197Ssam	sc->pmem = vtophys(sc->vmem);
198111119Simp	sc->pcibus = 1;
199105197Ssam	sc->win_size = 0x200000;
200120585Ssam	sc->win_bits = 21;
201105197Ssam	sc->csigs = &digi_normal_signals;
202105197Ssam	sc->status = DIGI_STATUS_NOTINIT;
203105197Ssam	callout_handle_init(&sc->callout);
204105197Ssam	callout_handle_init(&sc->inttest);
205105197Ssam	sc->setwin = digi_pci_setwin;
206105197Ssam	sc->hidewin = digi_pci_hidewin;
207105197Ssam	sc->towin = digi_pci_towin;
208105197Ssam
209105197Ssam	PCIPORT = FEPRST;
210105197Ssam
211105197Ssam	return (digi_attach(sc));
212105197Ssam}
213105197Ssam
214105197Ssamstatic device_method_t digi_pci_methods[] = {
215105197Ssam	/* Device interface */
216105197Ssam	DEVMETHOD(device_probe, digi_pci_probe),
217105197Ssam	DEVMETHOD(device_attach, digi_pci_attach),
218105197Ssam	DEVMETHOD(device_detach, digi_detach),
219105197Ssam	DEVMETHOD(device_shutdown, digi_shutdown),
220105197Ssam	{0, 0}
221105197Ssam};
222157123Sgnn
223105197Ssamstatic driver_t digi_pci_drv = {
224105197Ssam	"digi",
225105197Ssam	digi_pci_methods,
226105197Ssam	sizeof(struct digi_softc),
227105197Ssam};
228105197Ssam
229181803Sbz
230105197SsamDRIVER_MODULE(digi, pci, digi_pci_drv, digi_devclass, digi_modhandler, 0);
231105197Ssam