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