| 186 | struct rt_prio_queue *_bus_out_que; |
| 187 | |
| 188 | static void _bus_out_entry(void *param) |
| 189 | { |
| 190 | struct rt_vbus_pkg dpkg; |
| 191 | |
| 192 | _bus_out_que = rt_prio_queue_create("vbus", |
| 193 | _BUS_OUT_PKG_NR, |
| 194 | sizeof(struct rt_vbus_pkg)); |
| 195 | |
| 196 | if (!_bus_out_que) |
| 197 | { |
| 198 | rt_kprintf("could not create vmm bus queue\n"); |
| 199 | return; |
| 200 | } |
| 201 | |
| 202 | while (rt_prio_queue_pop(_bus_out_que, &dpkg, |
| 203 | RT_WAITING_FOREVER) == RT_EOK) |
| 204 | { |
| 205 | int sp; |
| 206 | rt_uint32_t nxtidx; |
| 207 | const int dnr = LEN2BNR(dpkg.len); |
| 208 | |
| 209 | #ifdef RT_VBUS_USING_FLOW_CONTROL |
| 210 | rt_wm_que_dec(&_chn_wm_que[dpkg.id]); |
| 211 | #endif |
| 212 | |
| 213 | if (!_chn_connected(dpkg.id)) |
| 214 | continue; |
| 215 | |
| 216 | sp = _bus_ring_space_nr(RT_VBUS_OUT_RING); |
| 217 | |
| 218 | vbus_debug("vmm bus out" |
| 219 | "(data: %p, len: %d, prio: %d, id: %d)\n", |
| 220 | dpkg.data, dpkg.len, dpkg.prio, dpkg.id); |
| 221 | |
| 222 | /* wait for enough space */ |
| 223 | while (sp < dnr) |
| 224 | { |
| 225 | rt_base_t level = rt_hw_interrupt_disable(); |
| 226 | |
| 227 | RT_VBUS_OUT_RING->blocked = 1; |
| 228 | rt_vbus_smp_wmb(); |
| 229 | |
| 230 | /* kick the guest, hoping this could force it do the work */ |
| 231 | rt_vbus_tick(0, RT_VBUS_GUEST_VIRQ); |
| 232 | |
| 233 | rt_thread_suspend(rt_thread_self()); |
| 234 | rt_schedule(); |
| 235 | |
| 236 | RT_VBUS_OUT_RING->blocked = 0; |
| 237 | |
| 238 | rt_hw_interrupt_enable(level); |
| 239 | |
| 240 | sp = _bus_ring_space_nr(RT_VBUS_OUT_RING); |
| 241 | } |
| 242 | |
| 243 | nxtidx = RT_VBUS_OUT_RING->put_idx + dnr; |
| 244 | |
| 245 | RT_VBUS_OUT_RING->blks[RT_VBUS_OUT_RING->put_idx].id = dpkg.id; |
nothing calls this directly
no test coverage detected