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