static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int l) { EHCIPCIState *i = DO_UPCAST(EHCIPCIState, pcidev, dev); bool busmaster; pci_default_write_config(dev, addr, val, l); if (!range_covers_byte(addr, l, PCI_COMMAND)) { return; } busmaster = pci_get_word(dev->config + PCI_COMMAND) & PCI_COMMAND_MASTER; i->ehci.dma = busmaster ? pci_dma_context(dev) : NULL; }
static int usb_ehci_pci_initfn(PCIDevice *dev) { EHCIPCIState *i = DO_UPCAST(EHCIPCIState, pcidev, dev); EHCIState *s = &i->ehci; uint8_t *pci_conf = dev->config; pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20); /* capabilities pointer */ pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00); /* pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x50); */ pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); /* interrupt pin D */ pci_set_byte(&pci_conf[PCI_MIN_GNT], 0); pci_set_byte(&pci_conf[PCI_MAX_LAT], 0); /* pci_conf[0x50] = 0x01; *//* power management caps */ pci_set_byte(&pci_conf[USB_SBRN], USB_RELEASE_2); /* release # (2.1.4) */ pci_set_byte(&pci_conf[0x61], 0x20); /* frame length adjustment (2.1.5) */ pci_set_word(&pci_conf[0x62], 0x00); /* port wake up capability (2.1.6) */ pci_conf[0x64] = 0x00; pci_conf[0x65] = 0x00; pci_conf[0x66] = 0x00; pci_conf[0x67] = 0x00; pci_conf[0x68] = 0x01; pci_conf[0x69] = 0x00; pci_conf[0x6a] = 0x00; pci_conf[0x6b] = 0x00; /* USBLEGSUP */ pci_conf[0x6c] = 0x00; pci_conf[0x6d] = 0x00; pci_conf[0x6e] = 0x00; pci_conf[0x6f] = 0xc0; /* USBLEFCTLSTS */ s->caps[0x09] = 0x68; /* EECP */ s->irq = dev->irq[3]; s->dma = pci_dma_context(dev); s->capsbase = 0x00; s->opregbase = 0x20; usb_ehci_initfn(s, DEVICE(dev)); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem); return 0; }
static int pci_ich9_ahci_init(PCIDevice *dev) { struct AHCIPCIState *d; int sata_cap_offset; uint8_t *sata_cap; d = DO_UPCAST(struct AHCIPCIState, card, dev); ahci_init(&d->ahci, &dev->qdev, pci_dma_context(dev), 6); pci_config_set_prog_interface(d->card.config, AHCI_PROGMODE_MAJOR_REV_1); d->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */ d->card.config[PCI_LATENCY_TIMER] = 0x00; /* Latency timer */ pci_config_set_interrupt_pin(d->card.config, 1); /* XXX Software should program this register */ d->card.config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */ msi_init(dev, 0x50, 1, true, false); d->ahci.irq = d->card.irq[0]; pci_register_bar(&d->card, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO, &d->ahci.idp); pci_register_bar(&d->card, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->ahci.mem); sata_cap_offset = pci_add_capability(&d->card, PCI_CAP_ID_SATA, ICH9_SATA_CAP_OFFSET, SATA_CAP_SIZE); if (sata_cap_offset < 0) { return sata_cap_offset; } sata_cap = d->card.config + sata_cap_offset; pci_set_word(sata_cap + SATA_CAP_REV, 0x10); pci_set_long(sata_cap + SATA_CAP_BAR, (ICH9_IDP_BAR + 0x4) | (ICH9_IDP_INDEX_LOG2 << 4)); d->ahci.idp_offset = ICH9_IDP_INDEX; return 0; }