{
USBPort *port;
USBPort **lastp;
+ USBDevice *dev;
int bus_num, addr;
const char *p;
if (!port)
return -1;
+ dev = port->dev;
*lastp = port->next;
usb_attach(port, NULL);
+ dev->handle_destroy(dev);
port->next = free_usb_ports;
free_usb_ports = port;
return 0;
}
/***********************************************************/
+/* bottom halves (can be seen as timers which expire ASAP) */
+
+struct QEMUBH {
+ QEMUBHFunc *cb;
+ void *opaque;
+ int scheduled;
+ QEMUBH *next;
+};
+
+static QEMUBH *first_bh = NULL;
+
+QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
+{
+ QEMUBH *bh;
+ bh = qemu_mallocz(sizeof(QEMUBH));
+ if (!bh)
+ return NULL;
+ bh->cb = cb;
+ bh->opaque = opaque;
+ return bh;
+}
+
+void qemu_bh_poll(void)
+{
+ QEMUBH *bh, **pbh;
+
+ for(;;) {
+ pbh = &first_bh;
+ bh = *pbh;
+ if (!bh)
+ break;
+ *pbh = bh->next;
+ bh->scheduled = 0;
+ bh->cb(bh->opaque);
+ }
+}
+
+void qemu_bh_schedule(QEMUBH *bh)
+{
+ CPUState *env = cpu_single_env;
+ if (bh->scheduled)
+ return;
+ bh->scheduled = 1;
+ bh->next = first_bh;
+ first_bh = bh;
+
+ /* stop the currently executing CPU to execute the BH ASAP */
+ if (env) {
+ cpu_interrupt(env, CPU_INTERRUPT_EXIT);
+ }
+}
+
+void qemu_bh_cancel(QEMUBH *bh)
+{
+ QEMUBH **pbh;
+ if (bh->scheduled) {
+ pbh = &first_bh;
+ while (*pbh != bh)
+ pbh = &(*pbh)->next;
+ *pbh = bh->next;
+ bh->scheduled = 0;
+ }
+}
+
+void qemu_bh_delete(QEMUBH *bh)
+{
+ qemu_bh_cancel(bh);
+ qemu_free(bh);
+}
+
+/***********************************************************/
/* machine registration */
QEMUMachine *first_machine = NULL;
#ifdef _WIN32
tap_win32_poll();
#endif
+ qemu_aio_poll();
+ qemu_bh_poll();
if (vm_running) {
qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
}
}
#endif
- init_timers();
- init_timer_alarm();
register_machines();
machine = first_machine;
setvbuf(stdout, NULL, _IOLBF, 0);
+ init_timers();
+ init_timer_alarm();
+ qemu_aio_init();
+
#ifdef _WIN32
socket_init();
#endif
snprintf(buf, sizeof(buf), "hd%c", i + 'a');
bs_table[i] = bdrv_new(buf);
}
- if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
+ if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
hd_filename[i]);
exit(1);
bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
}
if (fd_filename[i] != '\0') {
- if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
+ if (bdrv_open(fd_table[i], fd_filename[i],
+ snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
fd_filename[i]);
exit(1);
exit(1);
}
if (!strcmp(serial_devices[i], "vc"))
- qemu_chr_printf(serial_hds[i], "serial%d console\n", i);
+ qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
}
}
exit(1);
}
if (!strcmp(parallel_devices[i], "vc"))
- qemu_chr_printf(parallel_hds[i], "parallel%d console\n", i);
+ qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
}
}