Preserve logical device configuration on ISAPnP ROM update

This commit is contained in:
RichardG867
2021-06-03 14:18:21 -03:00
parent ea3d844826
commit ff46734e5e
2 changed files with 44 additions and 30 deletions

View File

@@ -53,7 +53,7 @@ static const uint8_t pnp_init_key[32] = { 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x
0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39 }; 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39 };
static const device_t isapnp_device; static const device_t isapnp_device;
#define ENABLE_ISAPNP_LOG 1
#ifdef ENABLE_ISAPNP_LOG #ifdef ENABLE_ISAPNP_LOG
int isapnp_do_log = ENABLE_ISAPNP_LOG; int isapnp_do_log = ENABLE_ISAPNP_LOG;
@@ -717,17 +717,15 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
isapnp_log("ISAPnP: Parsing ROM resources for card %c%c%c%02X%02X (serial %08X)\n", '@' + ((vendor >> 10) & 0x1f), '@' + ((vendor >> 5) & 0x1f), '@' + (vendor & 0x1f), card->rom[2], card->rom[3], (card->rom[7] << 24) | (card->rom[6] << 16) | (card->rom[5] << 8) | card->rom[4]); isapnp_log("ISAPnP: Parsing ROM resources for card %c%c%c%02X%02X (serial %08X)\n", '@' + ((vendor >> 10) & 0x1f), '@' + ((vendor >> 5) & 0x1f), '@' + (vendor & 0x1f), card->rom[2], card->rom[3], (card->rom[7] << 24) | (card->rom[6] << 16) | (card->rom[5] << 8) | card->rom[4]);
#endif #endif
uint16_t i = 9, j; uint16_t i = 9, j;
uint8_t ldn = 0, res, in_df = 0; uint8_t existing = 0, ldn = 0, res, in_df = 0;
uint8_t irq = 0, io = 0, mem_range = 0, mem_range_32 = 0, irq_df = 0, io_df = 0, mem_range_df = 0, mem_range_32_df = 0; uint8_t irq = 0, io = 0, mem_range = 0, mem_range_32 = 0, irq_df = 0, io_df = 0, mem_range_df = 0, mem_range_32_df = 0;
uint32_t len; uint32_t len;
isapnp_device_t *ld = card->first_ld, *prev_ld = NULL; isapnp_device_t *ld = NULL, *prev_ld = NULL;
/* Clear any existing logical devices. */ /* Check if this is an existing card which already has logical devices.
while (ld) { Any new logical devices will be added to the list after existing ones.
prev_ld = ld->next; Removed LDs are not flushed as we may end up with an invalid ROM. */
free(ld); existing = !!card->first_ld;
ld = prev_ld;
}
/* Iterate through ROM resources. */ /* Iterate through ROM resources. */
while (i < card->rom_size) { while (i < card->rom_size) {
@@ -805,22 +803,39 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
#endif #endif
/* We're done with the previous logical device. */ /* We're done with the previous logical device. */
if (ld) { if (ld && !existing)
prev_ld = ld;
isapnp_reset_ld_regs(ld); isapnp_reset_ld_regs(ld);
/* Look for an existing logical device with this number,
and create one if none exist. */
if (existing) {
ld = card->first_ld;
while (ld && (ld->number != ldn))
ld = ld->next;
}
if (ld) {
/* Reset some logical device state. */
ld->mem_upperlimit = ld->io_16bit = ld->irq_types = 0;
memset(ld->io_len, 0, sizeof(ld->io_len));
} else {
/* Create logical device. */
ld = (isapnp_device_t *) malloc(sizeof(isapnp_device_t));
memset(ld, 0, sizeof(isapnp_device_t));
/* Add to end of list. */
prev_ld = card->first_ld;
if (prev_ld) {
while (prev_ld->next)
prev_ld = prev_ld->next;
prev_ld->next = ld;
} else {
card->first_ld = ld;
}
} }
/* Create logical device. */ /* Set and increment logical device number. */
ld = (isapnp_device_t *) malloc(sizeof(isapnp_device_t));
memset(ld, 0, sizeof(isapnp_device_t));
ld->number = ldn++; ld->number = ldn++;
if (prev_ld)
prev_ld->next = ld;
else
card->first_ld = ld;
/* Start the position counts over. */ /* Start the position counts over. */
irq = io = mem_range = mem_range_32 = irq_df = io_df = mem_range_df = mem_range_32_df = 0; irq = io = mem_range = mem_range_32 = irq_df = io_df = mem_range_df = mem_range_32_df = 0;

View File

@@ -302,7 +302,7 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv)
if (!val) { if (!val) {
dev->ram_dl = 0; dev->ram_dl = 0;
/* Update PnP resource data and state. */ /* Update PnP state and resource data. */
cs423x_pnp_enable(dev, 1); cs423x_pnp_enable(dev, 1);
} }
break; break;
@@ -728,14 +728,6 @@ cs423x_init(const device_t *info)
break; break;
} }
/* Initialize SBPro codec first to get the correct CD audio filter for the default
context, which is SBPro. The WSS codec is initialized later by cs423x_reset */
dev->sb = (sb_t *) device_add(&sb_pro_cs423x_device);
/* Initialize RAM, registers and WSS codec. */
cs423x_reset(dev);
sound_add_handler(cs423x_get_buffer, dev);
/* Initialize I2C bus for the EEPROM. */ /* Initialize I2C bus for the EEPROM. */
dev->i2c = i2c_gpio_init("nvr_cs423x"); dev->i2c = i2c_gpio_init("nvr_cs423x");
@@ -745,7 +737,14 @@ cs423x_init(const device_t *info)
/* Initialize ISAPnP. */ /* Initialize ISAPnP. */
dev->pnp_card = isapnp_add_card(NULL, 0, cs423x_pnp_config_changed, NULL, NULL, NULL, dev); dev->pnp_card = isapnp_add_card(NULL, 0, cs423x_pnp_config_changed, NULL, NULL, NULL, dev);
cs423x_pnp_enable(dev, 1);
/* Initialize SBPro codec first to get the correct CD audio filter for the default
context, which is SBPro. The WSS codec is initialized later by cs423x_reset */
dev->sb = (sb_t *) device_add(&sb_pro_cs423x_device);
/* Initialize RAM, registers and WSS codec. */
cs423x_reset(dev);
sound_add_handler(cs423x_get_buffer, dev);
return dev; return dev;
} }