- 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) {
- if (cp + m->m_len > top) {
- printf("imp_snd: my packet runneth over\n");
- m_freem(m);
- return;
- }
- bcopy((int)m + m->m_off, cp, m->m_len);
- cp += m->m_len;
- MFREE(m, mp);
- m = mp;
- }
- }
- 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(ui->ui_hd->uh_uba, imp_stat.oaddr>>28);
- break;
-#endif
-#if defined(VAX750)
- case VAX_750:
- UBA_PURGE750(ui->ui_hd->uh_uba, imp_stat.oaddr>>28);
- 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 = IEN|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);