* Drain out max_messages for the buckets set in the bucket mask. * Use max_msgs = 0 to drain out all messages. */
| 173 | * Use max_msgs = 0 to drain out all messages. |
| 174 | */ |
| 175 | int |
| 176 | xlp_handle_msg_vc(u_int vcmask, int max_msgs) |
| 177 | { |
| 178 | struct nlm_fmn_msg msg; |
| 179 | int srcid = 0, size = 0, code = 0; |
| 180 | struct tx_stn_handler *he; |
| 181 | uint32_t mflags, status; |
| 182 | int n_msgs = 0, vc, m, hwtid; |
| 183 | u_int msgmask; |
| 184 | |
| 185 | hwtid = nlm_cpuid(); |
| 186 | for (;;) { |
| 187 | /* check if VC empty */ |
| 188 | mflags = nlm_save_flags_cop2(); |
| 189 | status = nlm_read_c2_msgstatus1(); |
| 190 | nlm_restore_flags(mflags); |
| 191 | |
| 192 | msgmask = ((status >> 24) & 0xf) ^ 0xf; |
| 193 | msgmask &= vcmask; |
| 194 | if (msgmask == 0) |
| 195 | break; |
| 196 | m = 0; |
| 197 | for (vc = 0; vc < 4; vc++) { |
| 198 | if ((msgmask & (1 << vc)) == 0) |
| 199 | continue; |
| 200 | |
| 201 | mflags = nlm_save_flags_cop2(); |
| 202 | status = nlm_fmn_msgrcv(vc, &srcid, &size, &code, |
| 203 | &msg); |
| 204 | nlm_restore_flags(mflags); |
| 205 | if (status != 0) /* no msg or error */ |
| 206 | continue; |
| 207 | if (srcid < 0 || srcid >= 1024) { |
| 208 | printf("[%s]: bad src id %d\n", __func__, |
| 209 | srcid); |
| 210 | continue; |
| 211 | } |
| 212 | he = &msgmap[srcid]; |
| 213 | if(he->action != NULL) |
| 214 | (he->action)(vc, size, code, srcid, &msg, |
| 215 | he->arg); |
| 216 | #if 0 |
| 217 | else |
| 218 | printf("[%s]: No Handler for msg from stn %d," |
| 219 | " vc=%d, size=%d, msg0=%jx, droppinge\n", |
| 220 | __func__, srcid, vc, size, |
| 221 | (uintmax_t)msg.msg[0]); |
| 222 | #endif |
| 223 | fmn_msgcount[hwtid][vc] += 1; |
| 224 | m++; /* msgs handled in this iter */ |
| 225 | } |
| 226 | if (m == 0) |
| 227 | break; /* nothing done in this iter */ |
| 228 | n_msgs += m; |
| 229 | if (max_msgs > 0 && n_msgs >= max_msgs) |
| 230 | break; |
| 231 | } |
| 232 |
no test coverage detected