Fixed save/restore support of the USB subsystem when using an external hub

with devices conected at runtime.
- Added restore handler support for the bx_list_c class. If a handler is
  registered, it will be called after restoring all of the list's members.
- USB hub: add special lists to the port state and add pointers to the
  runtime-only options for each port. The restore handler of this list calls
  init_device() to make sure all connected devices can be restored.
- Call restore_logopts() after restoring hardware to make sure all saved
  modules have been created.
- TODO: the USB cdrom also needs a fix for it's runtime-only options.
This commit is contained in:
Volker Ruppert 2015-08-28 17:37:38 +00:00
parent cc3020ab53
commit 7da8cfa4b0
6 changed files with 57 additions and 9 deletions

View File

@ -940,6 +940,7 @@ bx_list_c::bx_list_c(bx_param_c *parent, const char *name)
this->parent = (bx_list_c *)parent;
this->parent->add(this);
}
this->restore_handler = NULL;
init("");
}
@ -955,6 +956,7 @@ bx_list_c::bx_list_c(bx_param_c *parent, const char *name, const char *title)
this->parent = (bx_list_c *)parent;
this->parent->add(this);
}
this->restore_handler = NULL;
init(title);
}
@ -972,6 +974,7 @@ bx_list_c::bx_list_c(bx_param_c *parent, const char *name, const char *title, bx
this->parent = (bx_list_c *)parent;
this->parent->add(this);
}
this->restore_handler = NULL;
init(title);
}
@ -1137,3 +1140,15 @@ void bx_list_c::set_runtime_param(int val)
}
}
}
void bx_list_c::set_restore_handler(void *devptr, list_restore_handler restore)
{
sr_devptr = devptr;
restore_handler = restore;
}
void bx_list_c::restore()
{
if (restore_handler)
(*restore_handler)(sr_devptr, this);
}

View File

@ -446,6 +446,8 @@ typedef struct _bx_listitem_t {
struct _bx_listitem_t *next;
} bx_listitem_t;
typedef void (*list_restore_handler)(void *devptr, class bx_list_c *);
class BOCHSAPI bx_list_c : public bx_param_c {
protected:
// chained list of bx_listitem_t
@ -458,6 +460,9 @@ protected:
// title of the menu or series
char *title;
void init(const char *list_title);
// save / restore support
void *sr_devptr;
list_restore_handler restore_handler;
public:
enum {
// When a bx_list_c is displayed as a menu, SHOW_PARENT controls whether or
@ -505,6 +510,8 @@ public:
virtual void clear();
virtual void remove(const char *name);
virtual void set_runtime_param(int val);
void set_restore_handler(void *devptr, list_restore_handler restore);
void restore();
#if BX_USE_TEXTCONFIG
virtual void text_print(FILE *);
virtual int text_ask(FILE *fpin, FILE *fpout);

View File

@ -1236,14 +1236,16 @@ bx_bool bx_real_sim_c::restore_bochs_param(bx_list_c *root, const char *sr_path,
while (ptr) {
if (i == 0) {
if (!strcmp(ptr, "}")) {
base->restore();
base = (bx_list_c*)base->get_parent();
break;
} else {
param = get_param(ptr, base);
strncpy(pname, ptr, 80);
}
} else if (i == 2) {
if (param == NULL) {
BX_PANIC(("cannot find param!"));
BX_PANIC(("cannot find param '%s'!", pname));
}
else {
if (param->get_type() != BXT_LIST) {

View File

@ -166,6 +166,8 @@ static const Bit8u bx_hub_hub_descriptor[] =
static int hub_count = 0;
void usb_hub_restore_handler(void *dev, bx_list_c *conf);
usb_hub_device_c::usb_hub_device_c(Bit8u ports)
{
int i;
@ -229,12 +231,17 @@ void usb_hub_device_c::register_state_specific(bx_list_c *parent)
{
Bit8u i;
char portnum[6];
bx_list_c *port;
bx_list_c *port, *pconf, *config;
hub.state = new bx_list_c(parent, "hub", "USB HUB Device State");
for (i=0; i<hub.n_ports; i++) {
sprintf(portnum, "port%d", i+1);
port = new bx_list_c(hub.state, portnum);
pconf = (bx_list_c*)hub.config->get_by_name(portnum);
config = new bx_list_c(port, portnum);
config->add(pconf->get_by_name("device"));
config->add(pconf->get_by_name("options"));
config->set_restore_handler(this, usb_hub_restore_handler);
new bx_shadow_num_c(port, "PortStatus", &hub.usb_port[i].PortStatus, BASE_HEX);
new bx_shadow_num_c(port, "PortChange", &hub.usb_port[i].PortChange, BASE_HEX);
// empty list for USB device state
@ -685,4 +692,21 @@ const char *usb_hub_device_c::hub_param_handler(bx_param_string_c *param, int se
return val;
}
#undef LOG_THIS
#define LOG_THIS
void usb_hub_restore_handler(void *dev, bx_list_c *conf)
{
((usb_hub_device_c*)dev)->restore_handler(conf);
}
void usb_hub_device_c::restore_handler(bx_list_c *conf)
{
int i;
const char *pname = conf->get_name();
i = atoi(&pname[4]) - 1;
init_device(i, (bx_list_c*)SIM->get_param(pname, hub.config));
}
#endif // BX_SUPPORT_PCI && BX_SUPPORT_PCIUSB

View File

@ -44,6 +44,7 @@ public:
virtual void register_state_specific(bx_list_c *parent);
virtual void after_restore_state();
virtual void runtime_config();
void restore_handler(bx_list_c *conf);
private:
struct {

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2014 The Bochs Project
// Copyright (C) 2001-2015 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -1391,12 +1391,7 @@ void bx_init_hardware()
SIM->opt_plugin_ctrl("*", 0);
bx_pc_system.register_state();
DEV_register_state();
if (SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) {
if (!SIM->restore_logopts()) {
BX_PANIC(("cannot restore log options"));
SIM->get_param_bool(BXPN_RESTORE_FLAG)->set(0);
}
} else {
if (!SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) {
bx_set_log_actions_by_device(1);
}
@ -1405,6 +1400,10 @@ void bx_init_hardware()
if (SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) {
if (SIM->restore_hardware()) {
if (!SIM->restore_logopts()) {
BX_PANIC(("cannot restore log options"));
SIM->get_param_bool(BXPN_RESTORE_FLAG)->set(0);
}
bx_sr_after_restore_state();
} else {
BX_PANIC(("cannot restore hardware state"));