static void via_ide_set_irq(void *opaque, int n, int level) { PCIDevice *d = PCI_DEVICE(opaque); if (level) { d->config[0x70 + n * 8] |= 0x80; } else { d->config[0x70 + n * 8] &= ~0x80; } level = (d->config[0x70] & 0x80) || (d->config[0x78] & 0x80); n = pci_get_byte(d->config + PCI_INTERRUPT_LINE); if (n) { qemu_set_irq(isa_get_irq(NULL, n), level); } }
static uint8_t shpc_cap_dword(PCIDevice *d) { return pci_get_byte(d->config + d->shpc->cap + SHPC_CAP_DWORD_SELECT); }
static void shpc_command(SHPCDevice *shpc) { uint8_t code = pci_get_byte(shpc->config + SHPC_CMD_CODE); uint8_t speed; uint8_t target; uint8_t attn; uint8_t power; uint8_t state; int i; /* Clear status from the previous command. */ pci_word_test_and_clear_mask(shpc->config + SHPC_CMD_STATUS, SHPC_CMD_STATUS_BUSY | SHPC_CMD_STATUS_MRL_OPEN | SHPC_CMD_STATUS_INVALID_CMD | SHPC_CMD_STATUS_INVALID_MODE); switch (code) { case 0x00 ... 0x3f: target = shpc->config[SHPC_CMD_TRGT] & SHPC_CMD_TRGT_MAX; state = (code & SHPC_SLOT_STATE_MASK) >> SHPC_SLOT_STATE_SHIFT; power = (code & SHPC_SLOT_PWR_LED_MASK) >> SHPC_SLOT_PWR_LED_SHIFT; attn = (code & SHPC_SLOT_ATTN_LED_MASK) >> SHPC_SLOT_ATTN_LED_SHIFT; shpc_slot_command(shpc, target, state, power, attn); break; case 0x40 ... 0x47: speed = code & SHPC_SEC_BUS_MASK; shpc_set_sec_bus_speed(shpc, speed); break; case 0x48: /* Power only all slots */ /* first verify no slots are enabled */ for (i = 0; i < shpc->nslots; ++i) { state = shpc_get_status(shpc, i, SHPC_SLOT_STATE_MASK); if (state == SHPC_STATE_ENABLED) { shpc_invalid_command(shpc); goto done; } } for (i = 0; i < shpc->nslots; ++i) { if (!(shpc_get_status(shpc, i, SHPC_SLOT_STATUS_MRL_OPEN))) { shpc_slot_command(shpc, i + SHPC_CMD_TRGT_MIN, SHPC_STATE_PWRONLY, SHPC_LED_ON, SHPC_LED_NO); } else { shpc_slot_command(shpc, i + SHPC_CMD_TRGT_MIN, SHPC_STATE_NO, SHPC_LED_OFF, SHPC_LED_NO); } } break; case 0x49: /* Enable all slots */ /* TODO: Spec says this shall fail if some are already enabled. * This doesn't make sense - why not? a spec bug? */ for (i = 0; i < shpc->nslots; ++i) { state = shpc_get_status(shpc, i, SHPC_SLOT_STATE_MASK); if (state == SHPC_STATE_ENABLED) { shpc_invalid_command(shpc); goto done; } } for (i = 0; i < shpc->nslots; ++i) { if (!(shpc_get_status(shpc, i, SHPC_SLOT_STATUS_MRL_OPEN))) { shpc_slot_command(shpc, i + SHPC_CMD_TRGT_MIN, SHPC_STATE_ENABLED, SHPC_LED_ON, SHPC_LED_NO); } else { shpc_slot_command(shpc, i + SHPC_CMD_TRGT_MIN, SHPC_STATE_NO, SHPC_LED_OFF, SHPC_LED_NO); } } break; default: shpc_invalid_command(shpc); break; } done: pci_long_test_and_set_mask(shpc->config + SHPC_SERR_INT, SHPC_CMD_DETECTED); }