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