cy_pci.c revision 1.1
11.1Schristos/* $NetBSD: cy_pci.c,v 1.1 1996/09/24 17:59:33 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.1Schristos 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.1Schristos 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.1Schristos 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.1Schristos printf("%s: couldn't map PCI io region\n", sc->sc_dev.dv_xname); 691.1Schristos goto unmapmem; 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 vm_offset_t v_addr, p_addr; 981.1Schristos struct pci_attach_args *pa = aux; 991.1Schristos bus_io_handle_t ioh; 1001.1Schristos bus_mem_size_t memsize; 1011.1Schristos bus_io_size_t iosize; 1021.1Schristos int rv = 0; 1031.1Schristos struct cy_softc sc; 1041.1Schristos 1051.1Schristos if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CYCLADES) 1061.1Schristos return 0; 1071.1Schristos 1081.1Schristos switch (PCI_PRODUCT(pa->pa_id)) { 1091.1Schristos case PCI_PRODUCT_CYCLADES_CYCLOMY_1: 1101.1Schristos break; 1111.1Schristos case PCI_PRODUCT_CYCLADES_CYCLOMY_2: 1121.1Schristos break; 1131.1Schristos default: 1141.1Schristos return 0; 1151.1Schristos } 1161.1Schristos 1171.1Schristos#ifdef CY_DEBUG 1181.1Schristos printf("cy: Found Cyclades PCI device, id = 0x%x\n", pa->pa_id); 1191.1Schristos#endif 1201.1Schristos memcpy(&sc.sc_dev, match, sizeof(struct device)); 1211.1Schristos 1221.1Schristos sc.sc_bc = pa->pa_bc; 1231.1Schristos sc.sc_bustype = CY_BUSTYPE_PCI; 1241.1Schristos 1251.1Schristos if (cy_map_pci(pa, &sc, &ioh, &iosize, &memsize) == 0) 1261.1Schristos return 0; 1271.1Schristos 1281.1Schristos#ifdef CY_DEBUG 1291.1Schristos printf("%s: pci mapped mem 0x%lx (size %d), io 0x%x (size %d)\n", 1301.1Schristos sc.sc_dev.dv_xname, memaddr, memsize, iobase, iosize); 1311.1Schristos#endif 1321.1Schristos 1331.1Schristos if ((rv = cy_find(&sc)) == 0) 1341.1Schristos printf("%s: PCI Cyclom card with no CD1400s!?\n", 1351.1Schristos sc.sc_dev.dv_xname); 1361.1Schristos 1371.1Schristos cy_unmap_pci(&sc, ioh, iosize, memsize); 1381.1Schristos return rv; 1391.1Schristos} 1401.1Schristos 1411.1Schristos 1421.1Schristosstatic void 1431.1Schristoscy_attach_pci(parent, self, aux) 1441.1Schristos struct device *parent, *self; 1451.1Schristos void *aux; 1461.1Schristos{ 1471.1Schristos struct cy_softc *sc = (void *) self; 1481.1Schristos pci_intr_handle_t intrhandle; 1491.1Schristos bus_io_handle_t ioh; 1501.1Schristos bus_mem_size_t memsize; 1511.1Schristos bus_io_size_t iosize; 1521.1Schristos struct pci_attach_args *pa = aux; 1531.1Schristos 1541.1Schristos sc->sc_bc = pa->pa_bc; 1551.1Schristos sc->sc_bustype = CY_BUSTYPE_PCI; 1561.1Schristos 1571.1Schristos if (cy_map_pci(pa, sc, &ioh, &iosize, &memsize) == 0) 1581.1Schristos panic("%s: mapping failed", sc->sc_dev.dv_xname); 1591.1Schristos 1601.1Schristos if (cy_find(sc) == 0) 1611.1Schristos panic("%s: Cannot find card", sc->sc_dev.dv_xname); 1621.1Schristos 1631.1Schristos cy_attach(parent, self, aux); 1641.1Schristos 1651.1Schristos /* Enable PCI card interrupts */ 1661.1Schristos bus_io_write_2(sc->sc_bc, ioh, CY_PCI_INTENA, 1671.1Schristos bus_io_read_2(sc->sc_bc, ioh, CY_PCI_INTENA) | 0x900); 1681.1Schristos 1691.1Schristos if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, 1701.1Schristos pa->pa_intrline, &intrhandle) != 0) 1711.1Schristos panic("%s: couldn't map PCI interrupt", sc->sc_dev.dv_xname); 1721.1Schristos 1731.1Schristos 1741.1Schristos sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, 1751.1Schristos IPL_TTY, cy_intr, sc); 1761.1Schristos 1771.1Schristos if (sc->sc_ih == NULL) 1781.1Schristos panic("%s: couldn't establish interrupt", sc->sc_dev.dv_xname); 1791.1Schristos} 180