X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/04f32c3e67120f8498cdcf7926bab88e4e405258..ebb55b7e5f0b8f31328950ec383b77b208ffbb64:/lunaix-os/hal/bus/pci.c diff --git a/lunaix-os/hal/bus/pci.c b/lunaix-os/hal/bus/pci.c index af7a256..6d26d09 100644 --- a/lunaix-os/hal/bus/pci.c +++ b/lunaix-os/hal/bus/pci.c @@ -9,7 +9,6 @@ * */ #include -#include #include #include @@ -71,23 +70,19 @@ pci_create_device(pciaddr_t loc, ptr_t pci_base, int devinfo) } int -pci_bind_definition(struct pci_device_def* pcidev_def, int* more) +pci_bind_definition(struct pci_device_def* pcidef, bool* more) { - u32_t class = pcidev_def->dev_class; - u32_t devid_mask = pcidev_def->ident_mask; - u32_t devid = pcidev_def->dev_ident & devid_mask; - - if (!pcidev_def->devdef.bind) { + if (!pcidef->devdef.bind) { ERROR("pcidev %xh:%xh.%d is unbindable", - pcidev_def->devdef.class.fn_grp, - pcidev_def->devdef.class.device, - pcidev_def->devdef.class.variant); + pcidef->devdef.class.fn_grp, + pcidef->devdef.class.device, + pcidef->devdef.class.variant); return EINVAL; } - *more = 0; + *more = false; - int bind_attempted = 0; + bool bind_attempted = 0; int errno = 0; struct device_def* devdef; @@ -98,23 +93,22 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more) continue; } - if (class != PCI_DEV_CLASS(pos->class_info)) { - continue; - } + bool matched; - int matched = (pos->device_info & devid_mask) == devid; + assert(pcidef->test_compatibility); + matched = pcidef->test_compatibility(pcidef, pos); if (!matched) { continue; } if (bind_attempted) { - *more = 1; + *more = true; break; } - bind_attempted = 1; - devdef = &pcidev_def->devdef; + bind_attempted = true; + devdef = &pcidef->devdef; errno = devdef->bind(devdef, &pos->dev); if (errno) { @@ -127,7 +121,7 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more) continue; } - pos->binding.def = &pcidev_def->devdef; + pos->binding.def = &pcidef->devdef; } return errno; @@ -136,9 +130,10 @@ pci_bind_definition(struct pci_device_def* pcidev_def, int* more) int pci_bind_definition_all(struct pci_device_def* pcidef) { - int more = 0, e = 0; + int e = 0; + bool more = false; do { - if (!(e = pci_bind_definition(pcidef, &more))) { + if ((e = pci_bind_definition(pcidef, &more))) { break; } } while (more); @@ -201,7 +196,7 @@ pci_probe_bar_info(struct pci_device* device) { u32_t bar; struct pci_base_addr* ba; - for (size_t i = 0; i < 6; i++) { + for (size_t i = 0; i < PCI_BAR_COUNT; i++) { ba = &device->bar[i]; ba->size = pci_bar_sizing(device, &bar, i + 1); if (PCI_BAR_MMIO(bar)) { @@ -327,6 +322,21 @@ pci_get_device_by_class(u32_t class) return NULL; } +void +pci_apply_command(struct pci_device* pcidev, pci_reg_t cmd) +{ + pci_reg_t rcmd; + ptr_t base; + + base = pcidev->cspace_base; + rcmd = pci_read_cspace(base, PCI_REG_STATUS_CMD); + + cmd = cmd & 0xffff; + rcmd = (rcmd & 0xffff0000) | cmd; + + pci_write_cspace(base, PCI_REG_STATUS_CMD, rcmd); +} + static void __pci_read_cspace(struct twimap* map) {