cy_pci.c revision 1.3
11.3Schristos/*	$NetBSD: cy_pci.c,v 1.3 1996/10/13 01:38:18 christos Exp $	*/
21.1Schristos
31.1Schristos/*
41.1Schristos * cy_pci.c
51.1Schristos *
61.1Schristos * Driver for Cyclades Cyclom-8/16/32 multiport serial cards
71.1Schristos * (currently not tested with Cyclom-32 cards)
81.1Schristos *
91.1Schristos * Timo Rossi, 1996
101.1Schristos *
111.1Schristos */
121.1Schristos#include <sys/param.h>
131.1Schristos#include <sys/systm.h>
141.1Schristos#include <sys/device.h>
151.1Schristos
161.1Schristos#include <machine/bus.h>
171.1Schristos#include <machine/intr.h>
181.1Schristos
191.1Schristos#include <dev/pci/pcivar.h>
201.1Schristos#include <dev/pci/pcireg.h>
211.1Schristos#include <dev/pci/pcidevs.h>
221.1Schristos
231.1Schristos#include <dev/ic/cd1400reg.h>
241.1Schristos#include <dev/ic/cyreg.h>
251.1Schristos#include <dev/ic/cyvar.h>
261.1Schristos
271.1Schristosstatic int cy_probe_pci __P((struct device *, void *, void *));
281.1Schristosstatic void cy_attach_pci  __P((struct device *, struct device *, void *));
291.1Schristosstatic int cy_map_pci __P((struct pci_attach_args *, struct cy_softc *,
301.1Schristos    bus_io_handle_t *, bus_mem_size_t  *, bus_io_size_t *));
311.1Schristosstatic void cy_unmap_pci __P((struct cy_softc *, bus_io_handle_t,
321.1Schristos    bus_mem_size_t, bus_io_size_t));
331.1Schristos
341.1Schristosstruct cfattach cy_pci_ca = {
351.1Schristos	sizeof(struct cy_softc), cy_probe_pci, cy_attach_pci
361.1Schristos};
371.1Schristos
381.1Schristosstatic int
391.1Schristoscy_map_pci(pa, sc, ioh, iosize, memsize)
401.1Schristos	struct pci_attach_args *pa;
411.1Schristos	struct cy_softc *sc;
421.1Schristos	bus_io_handle_t *ioh;
431.1Schristos	bus_mem_size_t  *memsize;
441.1Schristos	bus_io_size_t *iosize;
451.1Schristos{
461.1Schristos	bus_io_addr_t iobase;
471.1Schristos	bus_mem_addr_t  memaddr;
481.1Schristos	int cacheable;
491.1Schristos
501.1Schristos	if (pci_mem_find(pa->pa_pc, pa->pa_tag, 0x18, &memaddr, memsize,
511.1Schristos	    &cacheable) != 0) {
521.3Schristos		printf("%s: can't find PCI card memory", sc->sc_dev.dv_xname);
531.1Schristos		return 0;
541.1Schristos	}
551.1Schristos	/* map the memory (non-cacheable) */
561.1Schristos	if (bus_mem_map(sc->sc_bc, memaddr, *memsize, 0, &sc->sc_memh) != 0) {
571.3Schristos		printf("%s: couldn't map PCI memory region\n",
581.1Schristos		    sc->sc_dev.dv_xname);
591.1Schristos		return 0;
601.1Schristos	}
611.1Schristos	/* the PCI Cyclom IO space is only used for enabling interrupts */
621.1Schristos	if (pci_io_find(pa->pa_pc, pa->pa_tag, 0x14, &iobase, iosize) != 0) {
631.3Schristos		printf("%s: couldn't find PCI io region\n",
641.1Schristos		    sc->sc_dev.dv_xname);
651.1Schristos		goto unmapmem;
661.1Schristos	}
671.1Schristos	if (bus_io_map(sc->sc_bc, iobase, *iosize, ioh) != 0) {
681.3Schristos		printf("%s: couldn't map PCI io region\n", sc->sc_dev.dv_xname);
691.2Schristos		goto unmapio;
701.1Schristos	}
711.1Schristos	return 1;
721.1Schristos
731.1Schristosunmapio:
741.1Schristos	bus_io_unmap(sc->sc_bc, *ioh, *iosize);
751.1Schristosunmapmem:
761.1Schristos	bus_mem_unmap(sc->sc_bc, sc->sc_memh, *memsize);
771.1Schristos	return 0;
781.1Schristos}
791.1Schristos
801.1Schristosstatic void
811.1Schristoscy_unmap_pci(sc, ioh, iosize, memsize)
821.1Schristos	struct cy_softc *sc;
831.1Schristos	bus_io_handle_t ioh;
841.1Schristos	bus_io_size_t iosize;
851.1Schristos	bus_mem_size_t  memsize;
861.1Schristos
871.1Schristos{
881.1Schristos	bus_io_unmap(sc->sc_bc, ioh, iosize);
891.1Schristos	bus_mem_unmap(sc->sc_bc, sc->sc_memh, memsize);
901.1Schristos}
911.1Schristos
921.1Schristosstatic int
931.1Schristoscy_probe_pci(parent, match, aux)
941.1Schristos	struct device  *parent;
951.1Schristos	void           *match, *aux;
961.1Schristos{
971.1Schristos	struct pci_attach_args *pa = aux;
981.1Schristos	bus_io_handle_t ioh;
991.1Schristos	bus_mem_size_t  memsize;
1001.1Schristos	bus_io_size_t iosize;
1011.1Schristos	int rv = 0;
1021.1Schristos	struct cy_softc sc;
1031.1Schristos
1041.1Schristos	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CYCLADES)
1051.1Schristos		return 0;
1061.1Schristos
1071.1Schristos	switch (PCI_PRODUCT(pa->pa_id)) {
1081.1Schristos	case PCI_PRODUCT_CYCLADES_CYCLOMY_1:
1091.1Schristos		break;
1101.1Schristos	case PCI_PRODUCT_CYCLADES_CYCLOMY_2:
1111.1Schristos		break;
1121.1Schristos	default:
1131.1Schristos		return 0;
1141.1Schristos	}
1151.1Schristos
1161.1Schristos#ifdef CY_DEBUG
1171.3Schristos	printf("cy: Found Cyclades PCI device, id = 0x%x\n", pa->pa_id);
1181.1Schristos#endif
1191.1Schristos	memcpy(&sc.sc_dev, match, sizeof(struct device));
1201.1Schristos
1211.1Schristos	sc.sc_bc = pa->pa_bc;
1221.1Schristos	sc.sc_bustype = CY_BUSTYPE_PCI;
1231.1Schristos
1241.1Schristos	if (cy_map_pci(pa, &sc, &ioh, &iosize, &memsize) == 0)
1251.1Schristos		return 0;
1261.1Schristos
1271.1Schristos#ifdef CY_DEBUG
1281.3Schristos	printf("%s: pci mapped mem 0x%lx (size %d), io 0x%x (size %d)\n",
1291.1Schristos	    sc.sc_dev.dv_xname, memaddr, memsize, iobase, iosize);
1301.1Schristos#endif
1311.1Schristos
1321.1Schristos	if ((rv = cy_find(&sc)) == 0)
1331.3Schristos		printf("%s: PCI Cyclom card with no CD1400s!?\n",
1341.1Schristos		    sc.sc_dev.dv_xname);
1351.1Schristos
1361.1Schristos	cy_unmap_pci(&sc, ioh, iosize, memsize);
1371.1Schristos	return rv;
1381.1Schristos}
1391.1Schristos
1401.1Schristos
1411.1Schristosstatic void
1421.1Schristoscy_attach_pci(parent, self, aux)
1431.1Schristos	struct device  *parent, *self;
1441.1Schristos	void *aux;
1451.1Schristos{
1461.1Schristos	struct cy_softc *sc = (void *) self;
1471.1Schristos	pci_intr_handle_t intrhandle;
1481.1Schristos	bus_io_handle_t ioh;
1491.1Schristos	bus_mem_size_t  memsize;
1501.1Schristos	bus_io_size_t iosize;
1511.1Schristos	struct pci_attach_args *pa = aux;
1521.1Schristos
1531.1Schristos	sc->sc_bc = pa->pa_bc;
1541.1Schristos	sc->sc_bustype = CY_BUSTYPE_PCI;
1551.1Schristos
1561.1Schristos	if (cy_map_pci(pa, sc, &ioh, &iosize, &memsize) == 0)
1571.1Schristos		panic("%s: mapping failed", sc->sc_dev.dv_xname);
1581.1Schristos
1591.1Schristos	if (cy_find(sc) == 0)
1601.1Schristos		panic("%s: Cannot find card", sc->sc_dev.dv_xname);
1611.1Schristos
1621.1Schristos	cy_attach(parent, self, aux);
1631.1Schristos
1641.1Schristos	/* Enable PCI card interrupts */
1651.1Schristos	bus_io_write_2(sc->sc_bc, ioh, CY_PCI_INTENA,
1661.1Schristos	    bus_io_read_2(sc->sc_bc, ioh, CY_PCI_INTENA) | 0x900);
1671.1Schristos
1681.1Schristos	if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
1691.1Schristos	    pa->pa_intrline, &intrhandle) != 0)
1701.1Schristos		panic("%s: couldn't map PCI interrupt", sc->sc_dev.dv_xname);
1711.1Schristos
1721.1Schristos
1731.1Schristos	sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle,
1741.1Schristos	    IPL_TTY, cy_intr, sc);
1751.1Schristos
1761.1Schristos	if (sc->sc_ih == NULL)
1771.1Schristos		panic("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
1781.1Schristos}
179