summary |
tags |
clone url |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
faad37c)
SCCS-vsn: sys/deprecated/netimp/raw_imp.c 4.2
SCCS-vsn: sys/vax/if/if_acc.c 4.2
SCCS-vsn: sys/deprecated/netimp/if_imp.c 4.3
-/* if_imp.c 4.2 82/02/01 */
+/* if_imp.c 4.3 82/02/01 */
#include "imp.h"
#if NIMP > 0
#include "imp.h"
#if NIMP > 0
COUNT(IMP_INPUT);
m = m0;
COUNT(IMP_INPUT);
m = m0;
+
+ /*
+ * We should generate a "bad leader" message
+ * to the IMP about messages too short.
+ */
if (m->m_len < sizeof(struct imp_leader) &&
m_pullup(m, sizeof(struct imp_leader)) == 0)
goto drop;
ip = mtod(m, struct imp_leader *);
if (m->m_len < sizeof(struct imp_leader) &&
m_pullup(m, sizeof(struct imp_leader)) == 0)
goto drop;
ip = mtod(m, struct imp_leader *);
- /* check leader type. */
+ /*
+ * Check leader type -- should notify IMP
+ * in case of failure...
+ */
if (ip->il_format != IMP_NFF)
goto drop;
if (ip->il_format != IMP_NFF)
goto drop;
case IMPTYPE_HOSTDEAD:
case IMPTYPE_HOSTUNREACH:
case IMPTYPE_BADDATA:
case IMPTYPE_HOSTDEAD:
case IMPTYPE_HOSTUNREACH:
case IMPTYPE_BADDATA:
- addr.s_host = ntohs(ip->il_host);
+ addr.s_host = ntohs(ip->il_host); /* XXX */
hp = h_lookup(addr);
break;
}
hp = h_lookup(addr);
break;
}
* Data for a protocol. Dispatch to the appropriate
* protocol routine (running at software interrupt).
* If this isn't a raw interface, advance pointer
* Data for a protocol. Dispatch to the appropriate
* protocol routine (running at software interrupt).
* If this isn't a raw interface, advance pointer
- * into mbuf past leader.
+ * into mbuf past leader (done below).
*/
case IMPTYPE_DATA:
ip->il_length = ntohs(ip->il_length) >> 3;
*/
case IMPTYPE_DATA:
ip->il_length = ntohs(ip->il_length) >> 3;
* IMP leader error. Reset the IMP and discard the packet.
*/
case IMPTYPE_BADLEADER:
* IMP leader error. Reset the IMP and discard the packet.
*/
case IMPTYPE_BADLEADER:
- imperr(sc, "leader error");
- h_reset(sc->imp_if.if_net); /* XXX */
- impnoops(sc);
+ /*
+ * According to 1822 document, this message
+ * will be generated in response to the
+ * first noop sent to the IMP after
+ * the host resets the IMP interface.
+ */
+ if (sc->imp_state != IMPS_RESET) {
+ imperr(sc, "leader error");
+ h_reset(sc->imp_if.if_net); /* XXX */
+ impnoops(sc);
+ }
case IMPTYPE_DOWN:
if ((ip->il_link & IMP_DMASK) == 0) {
sc->imp_state = IMPS_GOINGDOWN;
case IMPTYPE_DOWN:
if ((ip->il_link & IMP_DMASK) == 0) {
sc->imp_state = IMPS_GOINGDOWN;
- sc->imp_timer = IMPTV_DOWN;
+ timeout(impdown, sc, 30 * 60 * HZ);
}
imperr(sc, "going down %s", impmsg[ip->il_link & IMP_DMASK]);
goto drop;
}
imperr(sc, "going down %s", impmsg[ip->il_link & IMP_DMASK]);
goto drop;
* Reset the local address notion if it doesn't match.
*/
case IMPTYPE_NOOP:
* Reset the local address notion if it doesn't match.
*/
case IMPTYPE_NOOP:
+ if (sc->imp_state == IMPS_DOWN) {
+ sc->imp_state = IMPS_INIT;
+ sc->imp_dropcnt = IMP_DROPCNT;
+ }
if (sc->imp_state == IMPS_INIT && --sc->imp_dropcnt == 0) {
sc->imp_state = IMPS_UP;
/* restart output in case something was q'd */
if (sc->imp_state == IMPS_INIT && --sc->imp_dropcnt == 0) {
sc->imp_state = IMPS_UP;
/* restart output in case something was q'd */
* RFNM or INCOMPLETE message, record in
* host table and prime output routine.
*
* RFNM or INCOMPLETE message, record in
* host table and prime output routine.
*
- * SHOULD RETRANSMIT ON INCOMPLETE.
+ * SHOULD NOTIFY PROTOCOL ABOUT INCOMPLETES.
*/
case IMPTYPE_RFNM:
case IMPTYPE_INCOMPLETE:
*/
case IMPTYPE_RFNM:
case IMPTYPE_INCOMPLETE:
- if (sc->imp_state == IMPS_DOWN)
- sc->imp_state = IMPS_UP;
- else
- imperr(sc, "unexpected reset");
+ imperr(sc, "interface reset");
+ sc->imp_state = IMPS_RESET;
+ impnoops(sc);
+/*
+ * Bring the IMP down after notification.
+ */
+impdown(sc)
+ struct imp_softc *sc;
+{
+ sc->imp_state = IMPS_DOWN;
+ /* notify protocols with messages waiting? */
+}
+
/*VARARGS*/
imperr(sc, fmt, a1, a2)
struct imp_softc *sc;
/*VARARGS*/
imperr(sc, fmt, a1, a2)
struct imp_softc *sc;
/*
* Don't even try if the IMP is unavailable.
*/
/*
* Don't even try if the IMP is unavailable.
*/
- if (imp_softc[ifp->if_unit].imp_state == IMPS_DOWN) {
- m_freem(m0);
- return (0);
- }
+ x = imp_softc[ifp->if_unit].imp_state;
+ if (x == IMPS_DOWN || x == IMPS_GOINGDOWN)
+ goto drop;
default:
printf("imp%d: can't encapsulate pf%d\n", ifp->if_unit, pf);
default:
printf("imp%d: can't encapsulate pf%d\n", ifp->if_unit, pf);
- m_freem(m0);
- return (0);
if (m->m_off > MMAXOFF ||
MMINOFF + sizeof(struct imp_leader) > m->m_off) {
m = m_get(M_DONTWAIT);
if (m->m_off > MMAXOFF ||
MMINOFF + sizeof(struct imp_leader) > m->m_off) {
m = m_get(M_DONTWAIT);
- if (m == 0) {
- m_freem(m0);
- return (0);
- }
+ if (m == 0)
+ goto drop;
m->m_next = m0;
m->m_off = MMINOFF;
m->m_len = sizeof(struct imp_leader);
m->m_next = m0;
m->m_off = MMINOFF;
m->m_len = sizeof(struct imp_leader);
* and eventual transmission.
*/
return (impsnd(ifp, m));
* and eventual transmission.
*/
return (impsnd(ifp, m));
+drop:
+ m_freem(m0);
+ return (0);
- * If IMP would block, queue until rfnm
+ * If IMP would block, queue until RFNM
*/
if (hp) {
register struct mbuf *n;
*/
if (hp) {
register struct mbuf *n;
cnt++;
if (cnt >= 8)
goto drop;
cnt++;
if (cnt >= 8)
goto drop;
+
+ /*
+ * Q is kept as circulare list with h_q
+ * (head) pointing to the last entry.
+ */
if ((n = hp->h_q) == 0)
hp->h_q = m->m_act = m;
else {
if ((n = hp->h_q) == 0)
hp->h_q = m->m_act = m;
else {
-/* raw_imp.c 4.1 82/02/01 */
+/* raw_imp.c 4.2 82/02/01 */
#include "../h/param.h"
#include "../h/mbuf.h"
#include "../h/param.h"
#include "../h/mbuf.h"
{
struct mbuf *n;
int len;
{
struct mbuf *n;
int len;
- register struct imp_leader *il;
+ register struct imp_leader *ip;
register struct sockaddr_in *sin;
register struct rawcb *rp = sotorawcb(so);
register struct sockaddr_in *sin;
register struct rawcb *rp = sotorawcb(so);
if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct imp_leader)) &&
(m = m_pullup(m, sizeof(struct imp_leader))) == 0)
goto bad;
if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct imp_leader)) &&
(m = m_pullup(m, sizeof(struct imp_leader))) == 0)
goto bad;
- il = mtod(m, struct imp_leader *);
- if (il->il_format != IMP_NFF)
+ ip = mtod(m, struct imp_leader *);
+ if (ip->il_format != IMP_NFF)
- if (il->il_link != IMPLINK_IP &&
- (il->il_link < IMPLINK_LOWEXPER || il->il_link > IMPLINK_HIGHEXPER))
+ if (ip->il_link != IMPLINK_IP &&
+ (ip->il_link < IMPLINK_LOWEXPER || ip->il_link > IMPLINK_HIGHEXPER))
*/
for (len = 0, n = m; n; n = n->m_next)
len += n->m_len;
*/
for (len = 0, n = m; n; n = n->m_next)
len += n->m_len;
- il->il_length = len << 3;
+ ip->il_length = len << 3;
sin = (struct sockaddr_in *)&rp->rcb_addr;
sin = (struct sockaddr_in *)&rp->rcb_addr;
- il->il_network = sin->sin_addr.s_net;
- il->il_host = sin->sin_addr.s_host;
- il->il_imp = sin->sin_addr.s_imp;
+ ip->il_network = sin->sin_addr.s_net;
+ ip->il_host = sin->sin_addr.s_host;
+ ip->il_imp = sin->sin_addr.s_imp;
return (impoutput((struct ifnet *)rp->rcb_pcb, m, PF_IMPLINK));
return (impoutput((struct ifnet *)rp->rcb_pcb, m, PF_IMPLINK));
-/* if_acc.c 4.1 82/02/01 */
+/* if_acc.c 4.2 82/02/01 */
#include "acc.h"
#ifdef NACC > 0
#include "acc.h"
#ifdef NACC > 0
struct mbuf *acc_iq; /* input reassembly queue */
short acc_olen; /* size of last message sent */
char acc_flush; /* flush remainder of message */
struct mbuf *acc_iq; /* input reassembly queue */
short acc_olen; /* size of last message sent */
char acc_flush; /* flush remainder of message */
- char acc_previous; /* something on input queue */
}
addr = (struct accdevice *)ui->ui_addr;
}
addr = (struct accdevice *)ui->ui_addr;
- /* reset the imp interface. */
+ /*
+ * Reset the imp interface.
+ * the delays are totally guesses
+ */
x = spl5();
addr->acc_icsr = ACC_RESET;
x = spl5();
addr->acc_icsr = ACC_RESET;
addr->acc_ocsr = ACC_RESET;
addr->acc_ocsr = ACC_RESET;
addr->acc_ocsr = OUT_BBACK; /* reset host master ready */
addr->acc_ocsr = OUT_BBACK; /* reset host master ready */
addr->acc_ocsr = 0;
addr->acc_icsr = IN_MRDY; /* close the relay */
splx(x);
addr->acc_ocsr = 0;
addr->acc_icsr = IN_MRDY; /* close the relay */
splx(x);
(addr->acc_icsr & (IN_RMR | IN_IMPBSY))) {
/* keep turning IN_RMR off */
addr->acc_icsr = IN_MRDY;
(addr->acc_icsr & (IN_RMR | IN_IMPBSY))) {
/* keep turning IN_RMR off */
addr->acc_icsr = IN_MRDY;
- sleep((caddr_t)&lbolt, PZERO);
+ sleep((caddr_t)&lbolt, PZERO); /* ??? */
COUNT(ACCXINT);
if (sc->acc_ic->ic_oactive == 0) {
COUNT(ACCXINT);
if (sc->acc_ic->ic_oactive == 0) {
- printf("acc%d: stray output interrupt\n", unit);
+ printf("acc%d: stray send interrupt\n", unit);
return;
}
addr = (struct accdevice *)ui->ui_addr;
sc->acc_if->if_opackets++;
sc->acc_ic->ic_oactive = 0;
return;
}
addr = (struct accdevice *)ui->ui_addr;
sc->acc_if->if_opackets++;
sc->acc_ic->ic_oactive = 0;
- if (addr->acc_ocsr & ACC_ERR)
- printf("acc%d: output error, csr=%b\n", unit,
+ if (addr->acc_ocsr & ACC_ERR) {
+ printf("acc%d: send error, csr=%b\n", unit,
addr->acc_ocsr, ACC_OUTBITS);
addr->acc_ocsr, ACC_OUTBITS);
- if (sc->acc_if->if_snd.ifq_head == 0) {
sc->acc_if->if_oerrors++;
sc->acc_if->if_oerrors++;
+ }
+ if (sc->acc_if->if_snd.ifq_head == 0) {
if (sc->acc_ifuba.ifu_xtofree) {
m_freem(sc->acc_ifuba.ifu_xtofree);
sc->acc_ifuba.ifu_xtofree = 0;
if (sc->acc_ifuba.ifu_xtofree) {
m_freem(sc->acc_ifuba.ifu_xtofree);
sc->acc_ifuba.ifu_xtofree = 0;
if (m == 0)
goto setup;
if ((addr->acc_icsr & IN_EOM) == 0) {
if (m == 0)
goto setup;
if ((addr->acc_icsr & IN_EOM) == 0) {
- sc->acc_previous = 1;
- }
goto setup;
}
/* adjust message length for padding. */
m->m_len -= 2;
goto setup;
}
/* adjust message length for padding. */
m->m_len -= 2;
- if (sc->acc_previous) {
m_cat(sc->acc_iq, m);
m = sc->acc_iq;
sc->acc_iq = 0;
m_cat(sc->acc_iq, m);
m = sc->acc_iq;
sc->acc_iq = 0;