Home | History | Annotate | Line # | Download | only in isa
boca.c revision 1.1
      1 /*	$NetBSD: boca.c,v 1.1 1995/01/03 22:30:26 mycroft Exp $	*/
      2 
      3 /*
      4  * Multi-port serial card interrupt demuxing support.
      5  * Roland McGrath 3/20/94
      6  * The author disclaims copyright and places this file in the public domain.
      7  *
      8  * Modified by: Charles Hannum, 3/22/94
      9  *
     10  * The programming details of the BOCA board (i.e. how the interrupt register
     11  * works) were determined by David Muir Sharnoff.  BOCA Research refused to
     12  * provide any programming information.
     13  */
     14 
     15 #include <sys/param.h>
     16 #include <sys/device.h>
     17 
     18 #include <machine/pio.h>
     19 
     20 #include <i386/isa/isavar.h>
     21 
     22 struct boca_softc {
     23 	struct device sc_dev;
     24 	struct intrhand sc_ih;
     25 
     26 	int sc_iobase;
     27 	int sc_alive;		/* mask of slave units attached */
     28 	void *sc_slaves[8];	/* com device unit numbers */
     29 };
     30 
     31 int bocaprobe();
     32 void bocaattach();
     33 int bocaintr __P((struct boca_softc *));
     34 
     35 struct cfdriver bocacd = {
     36 	NULL, "boca", bocaprobe, bocaattach, DV_TTY, sizeof(struct boca_softc)
     37 };
     38 
     39 int
     40 bocaprobe(parent, self, aux)
     41 	struct device *parent, *self;
     42 	void *aux;
     43 {
     44 	struct isa_attach_args *ia = aux;
     45 
     46 	/*
     47 	 * Do the normal com probe for the first UART and assume
     48 	 * its presence means there is a multiport board there.
     49 	 * XXX Needs more robustness.
     50 	 */
     51 	ia->ia_iosize = 8 * 8;
     52 	return (comprobe1(ia->ia_iobase));
     53 }
     54 
     55 struct boca_attach_args {
     56 	int ba_slave;
     57 };
     58 
     59 int
     60 bocasubmatch(parent, match, aux)
     61 	struct device *parent;
     62 	void *match, *aux;
     63 {
     64 	struct boca_softc *sc = (void *)parent;
     65 	struct device *self = match;
     66 	struct isa_attach_args *ia = aux;
     67 	struct boca_attach_args *ba = ia->ia_aux;
     68 	struct cfdata *cf = self->dv_cfdata;
     69 
     70 	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ba->ba_slave)
     71 		return (0);
     72 	return ((*cf->cf_driver->cd_match)(parent, match, ia));
     73 }
     74 
     75 int
     76 bocaprint(aux, boca)
     77 	void *aux;
     78 	char *boca;
     79 {
     80 	struct isa_attach_args *ia = aux;
     81 	struct boca_attach_args *ba = ia->ia_aux;
     82 
     83 	printf(" slave %d", ba->ba_slave);
     84 }
     85 
     86 void
     87 bocaattach(parent, self, aux)
     88 	struct device *parent, *self;
     89 	void *aux;
     90 {
     91 	struct boca_softc *sc = (void *)self;
     92 	struct isa_attach_args *ia = aux;
     93 	struct boca_attach_args ba;
     94 	struct isa_attach_args isa;
     95 
     96 	sc->sc_iobase = ia->ia_iobase;
     97 
     98 	printf("\n");
     99 
    100 	isa.ia_aux = &ba;
    101 	for (ba.ba_slave = 0; ba.ba_slave < 8; ba.ba_slave++) {
    102 		struct cfdata *cf;
    103 		isa.ia_iobase = sc->sc_iobase + 8 * ba.ba_slave;
    104 		isa.ia_iosize = 0x666;
    105 		isa.ia_irq = IRQUNK;
    106 		isa.ia_drq = DRQUNK;
    107 		isa.ia_msize = 0;
    108 		if ((cf = config_search(bocasubmatch, self, &isa)) != 0) {
    109 			config_attach(self, cf, &isa, bocaprint);
    110 			sc->sc_slaves[ba.ba_slave] =
    111 			    cf->cf_driver->cd_devs[cf->cf_unit];
    112 			sc->sc_alive |= 1 << ba.ba_slave;
    113 		}
    114 	}
    115 
    116 	sc->sc_ih.ih_fun = bocaintr;
    117 	sc->sc_ih.ih_arg = sc;
    118 	sc->sc_ih.ih_level = IPL_TTY;
    119 	intr_establish(ia->ia_irq, IST_EDGE, &sc->sc_ih);
    120 }
    121 
    122 int
    123 bocaintr(sc)
    124 	struct boca_softc *sc;
    125 {
    126 	int iobase = sc->sc_iobase;
    127 	int alive = sc->sc_alive;
    128 	int bits;
    129 
    130 	bits = inb(iobase | 0x07) & alive;
    131 	if (bits == 0)
    132 		return (0);
    133 
    134 	for (;;) {
    135 #define	TRY(n) \
    136 		if (bits & (1 << (n))) \
    137 			comintr(sc->sc_slaves[n]);
    138 		TRY(0);
    139 		TRY(1);
    140 		TRY(2);
    141 		TRY(3);
    142 		TRY(4);
    143 		TRY(5);
    144 		TRY(6);
    145 		TRY(7);
    146 #undef TRY
    147 		bits = inb(iobase | 0x07) & alive;
    148 		if (bits == 0)
    149 			return (1);
    150  	}
    151 }
    152