static void pci_vtblk_qnotify(struct pci_vtblk_softc *sc) { struct vring_hqueue *hq = &sc->vbsc_q; int i; int ndescs; /* * Calculate number of ring entries to process */ ndescs = hq_num_avail(hq); if (ndescs == 0) return; /* * Run through all the entries, placing them into iovecs and * sending when an end-of-packet is found */ for (i = 0; i < ndescs; i++) pci_vtblk_proc(sc, hq); /* * Generate an interrupt if able */ if ((*hq->hq_avail_flags & VRING_AVAIL_F_NO_INTERRUPT) == 0 && sc->vbsc_isr == 0) { sc->vbsc_isr = 1; pci_generate_msi(sc->vbsc_pi, 0); } }
/* * WDT timer, start when guest OS start watchdog service; and re-start for * each dog-kick / ping action if time out, it will trigger reboot or other * action to guest OS */ static void wdt_expired_handler(void *arg, uint64_t nexp) { struct pci_vdev *dev = (struct pci_vdev *)arg; DPRINTF("wdt timer out! stage=%d, reboot=%d\n", wdt_state.stage, wdt_state.reboot_enabled); if (wdt_state.stage == 1) { if (wdt_state.intr_enabled) { if (pci_msi_enabled(dev)) pci_generate_msi(dev, 0); else pci_lintr_assert(dev); wdt_state.intr_active = true; } wdt_state.stage = 2; start_wdt_timer(); } else { if (wdt_state.reboot_enabled) { wdt_state.stage = 1; wdt_timeout = 1; /* watchdog timer out, set the uos to reboot */ vm_set_suspend_mode(VM_SUSPEND_FULL_RESET); mevent_notify(); } else { /* if not need reboot, just loop timer */ wdt_state.stage = 1; start_wdt_timer(); } } }