- if (!imp_stat.outactive) {
- if ((m = imp_stat.outq_head) == NULL)
- return;
- imp_stat.outactive = 1; /* set myself active */
- imp_stat.outq_head = m->m_act; /* -> next packet chain */
- /*
- * Pack mbufs into ethernet packet.
- */
- cp = (caddr_t)xpkt;
- top = (caddr_t)xpkt + sizeof(struct en_packet);
- while (m != NULL) {
- char *dp;
- if (cp + m->m_len > top) {
- printf("imp_snd: my packet runneth over\n");
- m_freem(m);
- return;
- }
- dp = mtod(m, char *);
- if (((int)cp&0x3ff)==0 && ((int)dp&0x3ff)==0) {
- struct pte *pte = &Mbmap[mtopf(dp)*2];
- *(int *)enxmr = enwproto | pte++->pg_pfnum;
- *(int *)(enxmr+1) = enwproto | pte->pg_pfnum;
- enxswapd = enxswapnow = 1;
- } else
- bcopy((int)m + m->m_off, cp, m->m_len);
- cp += m->m_len;
- /* too soon! */
- MFREE(m, mp);
- m = mp;
- }
- if (enxswapnow == 0 && enxswapd) {
- enxmr[0] = enxmap[0];
- enxmr[1] = enxmap[1];
- }
- if (enlastx && enlastx == xpkt->Header.en_dhost)
- imp_stat.endelay = enlastdel;
- else
- enlastx = xpkt->Header.en_dhost;
- }
- len = ntohs(((struct ip *)((int)xpkt + L1822))->ip_len) + L1822;
- if (len > sizeof(struct en_packet)) {
- printf("imp_output: ridiculous IP length %d\n", len);
- return;
- }
-#if defined(VAX780) || defined(VAX750)
- switch (cpu) {
-#if defined(VAX780)
- case VAX_780:
- UBA_PURGE780(enuba, enwbdp);
- break;
-#endif
-#if defined(VAX750)
- case VAX_750:
- UBA_PURGE750(enuba, enwbdp);
- break;
-#endif
- }
-#endif
- addr->en_oba = imp_stat.oaddr;
- addr->en_odelay = imp_stat.endelay;
- addr->en_owc = -((len + 1) >> 1);
-#ifdef IMPDEBUG
- printf("en%d: sending packet (%d bytes)\n", unit, len);
- prt_byte(xpkt, len);
-#endif
- addr->en_ostat = EN_IEN|EN_GO;
+ addr->en_istat = addr->en_ostat = 0;
+
+ /*
+ * Hang a receive and start any
+ * pending writes by faking a transmit complete.
+ */
+ s = splimp();
+ addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
+ addr->en_iwc = -(sizeof (struct en_header) + ENMTU) >> 1;
+ addr->en_istat = EN_IEN|EN_GO;
+ es->es_oactive = 1;
+ enxint(unit);
+ splx(s);