1 1.24 thorpej /* $NetBSD: cy_isa.c,v 1.24 2023/11/20 04:26:34 thorpej Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * cy.c 5 1.1 christos * 6 1.1 christos * Driver for Cyclades Cyclom-8/16/32 multiport serial cards 7 1.1 christos * (currently not tested with Cyclom-32 cards) 8 1.1 christos * 9 1.1 christos * Timo Rossi, 1996 10 1.1 christos */ 11 1.13 lukem 12 1.13 lukem #include <sys/cdefs.h> 13 1.24 thorpej __KERNEL_RCSID(0, "$NetBSD: cy_isa.c,v 1.24 2023/11/20 04:26:34 thorpej Exp $"); 14 1.1 christos 15 1.1 christos #include <sys/param.h> 16 1.1 christos #include <sys/systm.h> 17 1.1 christos #include <sys/device.h> 18 1.24 thorpej #include <sys/kmem.h> 19 1.1 christos 20 1.22 ad #include <sys/bus.h> 21 1.22 ad #include <sys/intr.h> 22 1.1 christos 23 1.1 christos #include <dev/isa/isavar.h> 24 1.1 christos #include <dev/isa/isareg.h> 25 1.1 christos 26 1.1 christos #include <dev/ic/cd1400reg.h> 27 1.1 christos #include <dev/ic/cyreg.h> 28 1.1 christos #include <dev/ic/cyvar.h> 29 1.1 christos 30 1.23 matt int cy_isa_probe(device_t, cfdata_t, void *); 31 1.23 matt void cy_isa_attach(device_t, device_t, void *); 32 1.1 christos 33 1.23 matt CFATTACH_DECL_NEW(cy_isa, sizeof(struct cy_softc), 34 1.17 thorpej cy_isa_probe, cy_isa_attach, NULL, NULL); 35 1.1 christos 36 1.11 thorpej int 37 1.23 matt cy_isa_probe(device_t parent, cfdata_t match, void *aux) 38 1.1 christos { 39 1.1 christos struct isa_attach_args *ia = aux; 40 1.24 thorpej struct cy_softc *sc; 41 1.24 thorpej int found = 0; 42 1.1 christos 43 1.14 thorpej if (ia->ia_niomem < 1) 44 1.14 thorpej return (0); 45 1.14 thorpej if (ia->ia_nirq < 1) 46 1.14 thorpej return (0); 47 1.14 thorpej 48 1.9 christos /* Disallow wildcarded memory address. */ 49 1.18 drochner if (ia->ia_iomem[0].ir_addr == ISA_UNKNOWN_IOMEM) 50 1.14 thorpej return 0; 51 1.18 drochner if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) 52 1.1 christos return 0; 53 1.1 christos 54 1.24 thorpej sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 55 1.24 thorpej 56 1.24 thorpej sc->sc_memt = ia->ia_memt; 57 1.24 thorpej sc->sc_bustype = CY_BUSTYPE_ISA; 58 1.24 thorpej 59 1.14 thorpej if (bus_space_map(ia->ia_memt, ia->ia_iomem[0].ir_addr, CY_MEMSIZE, 0, 60 1.24 thorpej &sc->sc_bsh) != 0) 61 1.24 thorpej goto out; 62 1.1 christos 63 1.24 thorpej found = cy_find(sc); 64 1.1 christos 65 1.24 thorpej bus_space_unmap(ia->ia_memt, sc->sc_bsh, CY_MEMSIZE); 66 1.1 christos 67 1.2 thorpej if (found) { 68 1.14 thorpej ia->ia_niomem = 1; 69 1.14 thorpej ia->ia_iomem[0].ir_size = CY_MEMSIZE; 70 1.14 thorpej 71 1.14 thorpej ia->ia_nirq = 1; 72 1.14 thorpej 73 1.14 thorpej ia->ia_nio = 0; 74 1.14 thorpej ia->ia_ndrq = 0; 75 1.2 thorpej } 76 1.24 thorpej out: 77 1.24 thorpej kmem_free(sc, sizeof(*sc)); 78 1.11 thorpej return (found); 79 1.1 christos } 80 1.1 christos 81 1.11 thorpej void 82 1.23 matt cy_isa_attach(device_t parent, device_t self, void *aux) 83 1.1 christos { 84 1.23 matt struct cy_softc *sc = device_private(self); 85 1.1 christos struct isa_attach_args *ia = aux; 86 1.1 christos 87 1.23 matt sc->sc_dev = self; 88 1.5 thorpej sc->sc_memt = ia->ia_memt; 89 1.1 christos sc->sc_bustype = CY_BUSTYPE_ISA; 90 1.1 christos 91 1.11 thorpej printf(": Cyclades-Y multiport serial\n"); 92 1.11 thorpej 93 1.14 thorpej if (bus_space_map(ia->ia_memt, ia->ia_iomem[0].ir_addr, CY_MEMSIZE, 0, 94 1.7 thorpej &sc->sc_bsh) != 0) { 95 1.23 matt aprint_error_dev(sc->sc_dev, 96 1.23 matt "unable to map device registers\n"); 97 1.7 thorpej return; 98 1.7 thorpej } 99 1.1 christos 100 1.7 thorpej if (cy_find(sc) == 0) { 101 1.23 matt aprint_error_dev(sc->sc_dev, "unable to find CD1400s\n"); 102 1.7 thorpej return; 103 1.7 thorpej } 104 1.1 christos 105 1.12 thorpej cy_attach(sc); 106 1.1 christos 107 1.14 thorpej sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, 108 1.1 christos IST_EDGE, IPL_TTY, cy_intr, sc); 109 1.1 christos if (sc->sc_ih == NULL) 110 1.23 matt aprint_error_dev(sc->sc_dev, "unable to establish interrupt\n"); 111 1.1 christos } 112