1*6827Ssam 2*6827Ssam #include "../h/param.h" 3*6827Ssam #include "../h/systm.h" 4*6827Ssam #include "../h/mbuf.h" 5*6827Ssam #include "../h/protosw.h" 6*6827Ssam #include "../h/socket.h" 7*6827Ssam #include "../h/socketvar.h" 8*6827Ssam #include "../net/dn_systm.h" 9*6827Ssam #include "../net/nsp.h" 10*6827Ssam #include "../net/nsp_var.h" 11*6827Ssam #include "../errno.h" 12*6827Ssam 13*6827Ssam /* 14*6827Ssam * NSP output routine: figure out what should be sent and send it. 15*6827Ssam */ 16*6827Ssam nsp_output(np) 17*6827Ssam register struct nspcb *np; 18*6827Ssam { 19*6827Ssam register struct socket *so = np->n_socket; 20*6827Ssam register int len; 21*6827Ssam int off, flags; 22*6827Ssam register struct mbuf *m; 23*6827Ssam 24*6827Ssam 25*6827Ssam /* 26*6827Ssam * Determine what type of message to send and send it. 27*6827Ssam */ 28*6827Ssam top: 29*6827Ssam /* interrupt to be sent? */ 30*6827Ssam if (np->n_flags & NF_INTAVAIL) && np->nf_remint > 0 && 31*6827Ssam (np->n_flags & NF_OTHSENT) == 0) { 32*6827Ssam register struct nspi *n; 33*6827Ssam 34*6827Ssam m = m_get(M_CANTWAIT); 35*6827Ssam if (m == 0) 36*6827Ssam return (0); 37*6827Ssam if (np->nb_xmt) 38*6827Ssam len = np->nb_xmt->m_len; 39*6827Ssam else 40*6827Ssam len = 0; 41*6827Ssam m->m_len = sizeof (struct nspi) + len; 42*6827Ssam m->m_off = MMAXOFF - m->m_len; 43*6827Ssam n = mtod(m, struct nspi *); 44*6827Ssam n->nsp_msgflg = NSP_INTR; 45*6827Ssam n->nsp_dstaddr = np->n_rem; 46*6827Ssam n->nsp_srcaddr = np->n_loc; 47*6827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 48*6827Ssam n->nsp_segnum = np->nn_oth; 49*6827Ssam if (len) 50*6827Ssam bcopy((char *)(n + 1), mtod(np->nb_xmt, char *), len); 51*6827Ssam if (tp_output(m, np->n_node)) { 52*6827Ssam m_free(m); 53*6827Ssam return (0); 54*6827Ssam } 55*6827Ssam np->n_flags &= ~(NF_INTAVAIL|NF_OTHACK); 56*6827Ssam np->n_flags |= NF_OTHSENT; 57*6827Ssam if (len) 58*6827Ssam m_free(np->nb_xmt); 59*6827Ssam nsp_insrtq(m, np->nt_oth); 60*6827Ssam goto top; 61*6827Ssam } 62*6827Ssam 63*6827Ssam /* interrupt request to be sent? */ 64*6827Ssam if (np->nf_locint == NFL_SEND && (np->n_flags & NF_OTHSENT) == 0) { 65*6827Ssam register struct nspls *n; 66*6827Ssam 67*6827Ssam m = m_get(M_CANTWAIT); 68*6827Ssam if (m == 0) 69*6827Ssam return (0); 70*6827Ssam m->m_len = sizeof (struct nspls); 71*6827Ssam m->m_off = MMAXOFF - m->m_len; 72*6827Ssam n = mtod(m, struct nspls *); 73*6827Ssam n->nsp_msgflg = NSP_LS; 74*6827Ssam n->nsp_dstaddr = np->n_rem; 75*6827Ssam n->nsp_srcaddr = np->n_loc; 76*6827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 77*6827Ssam n->nsp_segnum = np->nn_oth; 78*6827Ssam n->nsp_lsflags = NSPLS_INTREQ | NSPLS_ON; 79*6827Ssam n->nsp_fcval = 1; 80*6827Ssam if (tp_output(m, np->n_node)) { 81*6827Ssam m_free(m); 82*6827Ssam return (0); 83*6827Ssam } 84*6827Ssam np->n_flags &= ~NF_OTHACK; 85*6827Ssam np->n_flags |= NF_OTHSENT; 86*6827Ssam nsp_insrtq(m, np->nt_oth); 87*6827Ssam goto top; 88*6827Ssam } 89*6827Ssam 90*6827Ssam /* data request to be sent? */ 91*6827Ssam if (np->nf_locdat > 0 && (np->n_flags & NF_OTHSENT == 0)) { 92*6827Ssam register struct nspls *n; 93*6827Ssam 94*6827Ssam m = m_get(M_CANTWAIT); 95*6827Ssam if (m == 0) 96*6827Ssam return (0); 97*6827Ssam m->m_len = sizeof (struct nspls); 98*6827Ssam m->m_off = MMAXOFF - m->m_len; 99*6827Ssam n = mtod(m, struct nspls *); 100*6827Ssam n->nsp_msgflg = NSP_LS; 101*6827Ssam n->nsp_dstaddr = np->n_rem; 102*6827Ssam n->nsp_srcaddr = np->n_loc; 103*6827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 104*6827Ssam n->nsp_segnum = np->nn_oth; 105*6827Ssam n->nsp_lsflags = NSPLS_DATREQ | NSPLS_ON; 106*6827Ssam n->nsp_fcval = np->nf_locdat; 107*6827Ssam if (tp_output(m, np->n_node)) { 108*6827Ssam m_free(m); 109*6827Ssam return (0); 110*6827Ssam } 111*6827Ssam np->n_flags &= ~NF_OTHACK; 112*6827Ssam np->n_flags |= NF_OTHSENT; 113*6827Ssam nsp_insrtq(m, np->nt_oth); 114*6827Ssam goto top; 115*6827Ssam } 116*6827Ssam 117*6827Ssam /* other data ack to be sent? */ 118*6827Ssam if (np->n_flags & NF_OTHACK) { 119*6827Ssam register struct nspack *n; 120*6827Ssam 121*6827Ssam m = m_get(M_CANTWAIT); 122*6827Ssam if (m == 0) 123*6827Ssam return (0); 124*6827Ssam m->m_len = sizeof (struct nspack); 125*6827Ssam m->m_off = MMAXOFF - m->m_len; 126*6827Ssam n = mtod(m, struct nspack *); 127*6827Ssam n->nsp_msgflg = NSP_OTHACK; 128*6827Ssam n->nsp_dstaddr = np->n_rem; 129*6827Ssam n->nsp_srcaddr = np->n_loc; 130*6827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtoth; 131*6827Ssam if (tp_output(m, np->n_node)) { 132*6827Ssam m_free(m); 133*6827Ssam return (0); 134*6827Ssam } 135*6827Ssam np->n_flags &= ~NF_OTHACK; 136*6827Ssam m_free(m); 137*6827Ssam goto top; 138*6827Ssam } 139*6827Ssam 140*6827Ssam /* data to be sent? */ 141*6827Ssam if () { 142*6827Ssam register struct nspd *n; 143*6827Ssam 144*6827Ssam m = nsp_mgetcl(); 145*6827Ssam if (m == 0) 146*6827Ssam return (0); 147*6827Ssam if (len <= np->n_segsize) { 148*6827Ssam m->m_next = so->so_snd.sb_mb; 149*6827Ssam so->so_snd.sb_mb = m->m_next->m_act; 150*6827Ssam } 151*6827Ssam 152*6827Ssam /* MORE */ 153*6827Ssam 154*6827Ssam } 155*6827Ssam 156*6827Ssam /* data ack to be sent? */ 157*6827Ssam if (np->n_flags & NF_DATACK) { 158*6827Ssam register struct nspack *n; 159*6827Ssam 160*6827Ssam m = m_get(M_CANTWAIT); 161*6827Ssam if (m == 0) 162*6827Ssam return (0); 163*6827Ssam m->m_len = sizeof (struct nspack); 164*6827Ssam m->m_off = MMAXOFF - m->m_len; 165*6827Ssam n = mtod(m, struct nspack *); 166*6827Ssam n->nsp_msgflg = NSP_DATACK; 167*6827Ssam n->nsp_dstaddr = np->n_rem; 168*6827Ssam n->nsp_srcaddr = np->n_loc; 169*6827Ssam n->nsp_acknum = NSPA_ACK | np->na_xmtdat; 170*6827Ssam if (tp_output(m, np->n_node)) { 171*6827Ssam m_free(m); 172*6827Ssam return (0); 173*6827Ssam } 174*6827Ssam np->n_flags &= ~NF_DATACK; 175*6827Ssam m_free(m); 176*6827Ssam goto top; 177*6827Ssam } 178*6827Ssam 179*6827Ssam /* 180*6827Ssam * Nothing left to do, return success. 181*6827Ssam */ 182*6827Ssam return (1); 183*6827Ssam } 184