+ while (addr->bsel2 & DMC_RDYO) {
+
+ cmd = addr->bsel2 & 0xff;
+ arg = addr->sel6 & 0xffff;
+ /* reconstruct UNIBUS address of buffer returned to us */
+ pkaddr = ((arg&DMC_XMEM)<<2) | (addr->sel4 & 0xffff);
+ /* release port */
+ addr->bsel2 &= ~DMC_RDYO;
+ switch (cmd & 07) {
+
+ case DMC_OUR:
+ /*
+ * A read has completed.
+ * Pass packet to type specific
+ * higher-level input routine.
+ */
+ ifp->if_ipackets++;
+ /* find location in dmcuba struct */
+ ifrw= &sc->sc_ifuba.ifu_r[0];
+ for (rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[NRCV]; rp++) {
+ if(rp->ubinfo == pkaddr)
+ break;
+ ifrw++;
+ }
+ if (rp >= &sc->sc_rbufs[NRCV])
+ panic("dmc rcv");
+ if ((rp->flags & DBUF_DMCS) == 0)
+ printf("dmc%d: done unalloc rbuf\n", unit);
+
+ len = (arg & DMC_CCOUNT) - sizeof (struct dmc_header);
+ if (len < 0 || len > DMCMTU) {
+ ifp->if_ierrors++;
+ printd("dmc%d: bad rcv pkt addr 0x%x len 0x%x\n",
+ unit, pkaddr, len);
+ goto setup;
+ }
+ /*
+ * Deal with trailer protocol: if type is trailer
+ * get true type from first 16-bit word past data.
+ * Remember that type was trailer by setting off.
+ */
+ dh = (struct dmc_header *)ifrw->ifrw_addr;
+ dh->dmc_type = ntohs((u_short)dh->dmc_type);
+#define dmcdataaddr(dh, off, type) ((type)(((caddr_t)((dh)+1)+(off))))
+ if (dh->dmc_type >= DMC_TRAILER &&
+ dh->dmc_type < DMC_TRAILER+DMC_NTRAILER) {
+ off = (dh->dmc_type - DMC_TRAILER) * 512;
+ if (off >= DMCMTU)
+ goto setup; /* sanity */
+ dh->dmc_type = ntohs(*dmcdataaddr(dh, off, u_short *));
+ resid = ntohs(*(dmcdataaddr(dh, off+2, u_short *)));
+ if (off + resid > len)
+ goto setup; /* sanity */
+ len = off + resid;
+ } else
+ off = 0;
+ if (len == 0)
+ goto setup;
+
+ /*
+ * Pull packet off interface. Off is nonzero if
+ * packet has trailing header; dmc_get will then
+ * force this header information to be at the front,
+ * but we still have to drop the type and length
+ * which are at the front of any trailer data.
+ */
+ m = dmc_get(&sc->sc_ifuba, ifrw, len, off);
+ if (m == 0)
+ goto setup;
+ if (off) {
+ m->m_off += 2 * sizeof (u_short);
+ m->m_len -= 2 * sizeof (u_short);
+ }
+ switch (dh->dmc_type) {