void renew_pseudo_associations(grammar_t g) { for(meaning_t m=0; m<meanings; m++) { for(signal_t s=0; s<signals; s++) { g->msp[m*signals+s] = (1.0 - meaning_leakage - signal_leakage) * get_association(g,m,s); // By default, a pseudo-association is the same as the assocation // Rattle through neighbours in meaning and signal space, and apply leakage if(meaning_leakage>0.0) { double wt = (double)mi_start(_gws.mi, m); wt = meaning_leakage / wt; // This might not be norm preserving on general meaning-signal networks while(mi_hasnext(_gws.mi)) { g->msp[m*signals+s] += get_association(g,mi_next(_gws.mi),s) * wt; } } if(signal_leakage>0.0) { double wt = (double)si_start(_gws.si, s); wt = signal_leakage / wt; // This might not be norm preserving on general meaning-signal networks while(si_hasnext(_gws.si)) { g->msp[m*signals+s] += get_association(g,m,si_next(_gws.si)) * wt; } } } } }
void si_intr(void *arg) { struct si_softc *sc; struct si_port *pp; volatile struct si_channel *ccbp; struct tty *tp; volatile caddr_t maddr; BYTE op, ip; int x, card, port, n, i, isopen; volatile BYTE *z; BYTE c; sc = arg; DPRINT((0, arg == NULL ? DBG_POLL:DBG_INTR, "si_intr\n")); if (in_intr) return; in_intr = 1; /* * When we get an int we poll all the channels and do ALL pending * work, not just the first one we find. This allows all cards to * share the same vector. * * XXX - But if we're sharing the vector with something that's NOT * a SI/XIO/SX card, we may be making more work for ourselves. */ for (card = 0; card < si_numunits; card++) { sc = devclass_get_softc(si_devclass, card); if (sc == NULL || sc->sc_type == SIEMPTY) continue; /* * First, clear the interrupt */ switch(sc->sc_type) { case SIHOST: maddr = sc->sc_maddr; ((volatile struct si_reg *)maddr)->int_pending = 0; /* flag nothing pending */ *(maddr+SIINTCL) = 0x00; /* Set IRQ clear */ *(maddr+SIINTCL_CL) = 0x00; /* Clear IRQ clear */ break; case SIHOST2: maddr = sc->sc_maddr; ((volatile struct si_reg *)maddr)->int_pending = 0; *(maddr+SIPLIRQCLR) = 0x00; *(maddr+SIPLIRQCLR) = 0x10; break; case SIPCI: maddr = sc->sc_maddr; ((volatile struct si_reg *)maddr)->int_pending = 0; *(maddr+SIPCIINTCL) = 0x0; break; case SIJETPCI: /* fall through to JETISA case */ case SIJETISA: maddr = sc->sc_maddr; ((volatile struct si_reg *)maddr)->int_pending = 0; *(maddr+SIJETINTCL) = 0x0; break; #ifdef DEV_EISA case SIEISA: maddr = sc->sc_maddr; ((volatile struct si_reg *)maddr)->int_pending = 0; (void)inb(sc->sc_iobase + 3); break; #endif case SIEMPTY: default: continue; } ((volatile struct si_reg *)maddr)->int_scounter = 0; /* * check each port */ for (pp = sc->sc_ports, port = 0; port < sc->sc_nport; pp++, port++) { ccbp = pp->sp_ccb; tp = pp->sp_tty; /* * See if a command has completed ? */ if (ccbp->hi_stat != pp->sp_pend) { DPRINT((pp, DBG_INTR, "si_intr hi_stat = 0x%x, pend = %d\n", ccbp->hi_stat, pp->sp_pend)); switch(pp->sp_pend) { case LOPEN: case MPEND: case MOPEN: case CONFIG: case SBREAK: case EBREAK: pp->sp_pend = ccbp->hi_stat; /* sleeping in si_command */ wakeup(&pp->sp_state); break; default: pp->sp_pend = ccbp->hi_stat; } } /* * Continue on if it's closed */ if (ccbp->hi_stat == IDLE_CLOSE) { continue; } /* * Do modem state change if not a local device */ si_modem_state(pp, tp, ccbp->hi_ip); /* * Check to see if we should 'receive' characters. */ if (tp->t_state & TS_CONNECTED && tp->t_state & TS_ISOPEN) isopen = 1; else isopen = 0; /* * Do input break processing */ if (ccbp->hi_state & ST_BREAK) { if (isopen) { ttyld_rint(tp, TTY_BI); } ccbp->hi_state &= ~ST_BREAK; /* A Bit iffy this */ DPRINT((pp, DBG_INTR, "si_intr break\n")); } /* * Do RX stuff - if not open then dump any characters. * XXX: This is VERY messy and needs to be cleaned up. * * XXX: can we leave data in the host adapter buffer * when the clists are full? That may be dangerous * if the user cannot get an interrupt signal through. */ more_rx: /* XXX Sorry. the nesting was driving me bats! :-( */ if (!isopen) { ccbp->hi_rxopos = ccbp->hi_rxipos; goto end_rx; } /* * If the tty input buffers are blocked, stop emptying * the incoming buffers and let the auto flow control * assert.. */ if (tp->t_state & TS_TBLOCK) { goto end_rx; } /* * Process read characters if not skipped above */ op = ccbp->hi_rxopos; ip = ccbp->hi_rxipos; c = ip - op; if (c == 0) { goto end_rx; } n = c & 0xff; if (n > 250) n = 250; DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", n, op, ip)); /* * Suck characters out of host card buffer into the * "input staging buffer" - so that we dont leave the * host card in limbo while we're possibly echoing * characters and possibly flushing input inside the * ldisc l_rint() routine. */ if (n <= SI_BUFFERSIZE - op) { DPRINT((pp, DBG_INTR, "\tsingle copy\n")); z = ccbp->hi_rxbuf + op; si_vbcopy(z, si_rxbuf, n); op += n; } else { x = SI_BUFFERSIZE - op; DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x)); z = ccbp->hi_rxbuf + op; si_vbcopy(z, si_rxbuf, x); DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n", n - x)); z = ccbp->hi_rxbuf; si_vbcopy(z, si_rxbuf + x, n - x); op += n; } /* clear collected characters from buffer */ ccbp->hi_rxopos = op; DPRINT((pp, DBG_INTR, "n = %d, op = %d, ip = %d\n", n, op, ip)); /* * at this point... * n = number of chars placed in si_rxbuf */ /* * Avoid the grotesquely inefficient lineswitch * routine (ttyinput) in "raw" mode. It usually * takes about 450 instructions (that's without * canonical processing or echo!). slinput is * reasonably fast (usually 40 instructions * plus call overhead). */ if (tp->t_state & TS_CAN_BYPASS_L_RINT) { /* block if the driver supports it */ if (tp->t_rawq.c_cc + n >= SI_I_HIGH_WATER && (tp->t_cflag & CRTS_IFLOW || tp->t_iflag & IXOFF) && !(tp->t_state & TS_TBLOCK)) ttyblock(tp); tk_nin += n; tk_rawcc += n; tp->t_rawcc += n; pp->sp_delta_overflows += b_to_q((char *)si_rxbuf, n, &tp->t_rawq); ttwakeup(tp); if (tp->t_state & TS_TTSTOP && (tp->t_iflag & IXANY || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { tp->t_state &= ~TS_TTSTOP; tp->t_lflag &= ~FLUSHO; si_start(tp); } } else { /* * It'd be nice to not have to go through the * function call overhead for each char here. * It'd be nice to block input it, saving a * loop here and the call/return overhead. */ for(x = 0; x < n; x++) { i = si_rxbuf[x]; if (ttyld_rint(tp, i) == -1) { pp->sp_delta_overflows++; } } } goto more_rx; /* try for more until RXbuf is empty */ end_rx: /* XXX: Again, sorry about the gotos.. :-) */ /* * Do TX stuff */ ttyld_start(tp); } /* end of for (all ports on this controller) */ } /* end of for (all controllers) */ in_intr = 0; DPRINT((0, arg == NULL ? DBG_POLL:DBG_INTR, "end si_intr\n")); }