/************************************************************************/ /* */ /* ***** ***** */ /* ***** ***** */ /* ***** ***** */ /* ***** ***** */ /* *************** *************** */ /* ***************** ***************** */ /* *************** *************** */ /* ***** ***** TheNetNode */ /* ***** ***** Portable */ /* ***** ***** Network */ /* ***** ***** Software */ /* */ /* File os/go32/extdev.c (maintained by: ???) */ /* */ /* This file is part of "TheNetNode" - Software Package */ /* */ /* Copyright (C) 1998 - 2008 NORD>data, fp->len))->l2port = fp->port; relink((LEHEAD *)rxfhd, (LEHEAD *)rxfl.tail); } for (port = 0; port < L2PNUM; port++, l2flp++) {/* Ports durchsehen */ p = &portpar[port]; /* ob etwas zu senden ist */ if (p->major != ext_major) continue; if(kick[port]) { state = ext_state(port); /* Port-Zustand holen */ if (fullduplex(port)) state |= CH_FDX; if (((state & CH_FDX) == 0) && ((state & CH_PTT) == 0)) { /* Sender noch nicht an */ if (p->l1_tx_timer > ticks) { p->l1_tx_timer -= ticks; } else { if ((state & CH_DCD) || (state & CH_RXB) || (rand()%256>p->persistance)) p->l1_tx_timer = p->slottime; else p->l1_tx_timer = 0; } } else p->l1_tx_timer = 0; if (p->l1_tx_timer == 0) { if ((fp = l1_get_txbuf(port)) != NULL) { fp->len = 0; fp->port = port; fp->txdelay = portpar[port].txdelay; ulink((LEHEAD *)(txfhdl = (MBHEAD *) l2flp->head));/*Zeiger holen*/ if (txfhdl->mbpc < 400) fp->len = cpymbflat(fp->data, txfhdl); relink((LEHEAD *)txfhdl, /* als gesendet betrachten und in */ (LEHEAD *)stfl.tail); /* die gesendet Liste umhaengen */ kick[port] = ((LHEAD *)l2flp->head != l2flp); l1_kick(); } } } } } static WORD ext_dcd(PORTINFO *port) { int state = 0; int hw_state; hw_state = l1_state(port->minor); if (hw_state & CH_DCD) /* DCD an, kein Duplex, nicht */ state |= DCDFLAG; /* senden */ if (hw_state & CH_RXB) /* Daten im empfaenger, nicht */ state |= RXBFLAG; /* senden (auch bei Duplex) */ /* der externe Treiber sagt uns, wann die PTT wirklich an ist und nicht wann das letzte Zeichen raus ist, das ist fuer Duplex nicht zu gebrauchen, dafuer ist hier aber auch die Verzoegerung zwischen uebergabe an stfl und Sendung nicht so gross */ if (hw_state & CH_PTT) /* PTT an, kein Duplex, warten*/ state |= PTTFLAG; /* bis PTT aus */ return(state); } /* Durch die feste Bindung minor=port ist die Pruefung auf Doppelbelegung */ /* nicht notwendig. Man koennte das aendern, aber das verwirrt dann ganz */ /* schoen, wenn die Ports nicht in Ladereihenfolge genommen werden. */ static int ext_attach(int port, int unused_devnr, BOOLEAN check_only) { if (dev_irq > 0) if (port < l1_enum_ports()) { if (!check_only) portpar[port].minor = port; return(1); } return(0); } static void ext_info(int what, int port, MBHEAD *mbp) { char str[11]; L1STATISTICS *stat; int cnt; switch (what) { case HW_INF_IDENT : putstr("EXTDEV", mbp); break; case HW_INF_INFO : strncpy(str, l1_ident(port), 10); str[10] = 0; /* maximal 10 Zeichen */ putstr(str, mbp); break; case HW_INF_STAT : for (port = cnt = 0; port < l1_enum_ports(); port++) if (portpar[port].major == ext_major) { if (cnt++ == 0) putstr("\rExternal-Statistics:\r\r", mbp); stat = l1_stat(port, 0); putprintf(mbp, " %-10.10s TxErr: %5lu RxOvr: %5lu OFlow: %5lu IOErr: %5lu\r", l1_ident(port), stat->tx_error, stat->rx_overrun, stat->rx_bufferoverflow, stat->io_error); } break; case HW_INF_CLEAR : l1_stat(port, 1); /* durchfallen */ default : default_l1info(what, port, mbp); } } static void ext_ctl(int req, int port) { switch (req) { case L1CCMD : case L1CRES : l1_init_port(port, portpar[port].speed, portpar[port].l1mode); break; } default_l1ctl(req, port); /* Flags loeschen */ }; static int register_extdev(void) { MAJOR *m; if (find_devirq()) { /* Externes Interface suchen */ m = register_major(); m->name = "EXTDEV"; m->dcd = ext_dcd; m->attach = ext_attach; m->info = ext_info; m->timer = ext_timer; m->ctl = ext_ctl; return(ext_major = num_major); } return(0); } /* End of os/go32/extdev.c */