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