static void __init test_basics(void) { struct msi_bitmap bmp; int rc, i, size = 512; /* Can't allocate a bitmap of 0 irqs */ WARN_ON(msi_bitmap_alloc(&bmp, 0, NULL) == 0); /* of_node may be NULL */ WARN_ON(msi_bitmap_alloc(&bmp, size, NULL)); /* Should all be free by default */ WARN_ON(bitmap_find_free_region(bmp.bitmap, size, get_count_order(size))); bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); /* With no node, there's no msi-available-ranges, so expect > 0 */ WARN_ON(msi_bitmap_reserve_dt_hwirqs(&bmp) <= 0); /* Should all still be free */ WARN_ON(bitmap_find_free_region(bmp.bitmap, size, get_count_order(size))); bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); /* Check we can fill it up and then no more */ for (i = 0; i < size; i++) WARN_ON(msi_bitmap_alloc_hwirqs(&bmp, 1) < 0); WARN_ON(msi_bitmap_alloc_hwirqs(&bmp, 1) >= 0); /* Should all be allocated */ WARN_ON(bitmap_find_free_region(bmp.bitmap, size, 0) >= 0); /* And if we free one we can then allocate another */ msi_bitmap_free_hwirqs(&bmp, size / 2, 1); WARN_ON(msi_bitmap_alloc_hwirqs(&bmp, 1) != size / 2); /* Free most of them for the alignment tests */ msi_bitmap_free_hwirqs(&bmp, 3, size - 3); /* Check we get a naturally aligned offset */ rc = msi_bitmap_alloc_hwirqs(&bmp, 2); WARN_ON(rc < 0 && rc % 2 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 4); WARN_ON(rc < 0 && rc % 4 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 8); WARN_ON(rc < 0 && rc % 8 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 9); WARN_ON(rc < 0 && rc % 16 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 3); WARN_ON(rc < 0 && rc % 4 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 7); WARN_ON(rc < 0 && rc % 8 != 0); rc = msi_bitmap_alloc_hwirqs(&bmp, 121); WARN_ON(rc < 0 && rc % 128 != 0); msi_bitmap_free(&bmp); /* Clients may WARN_ON bitmap == NULL for "not-allocated" */ WARN_ON(bmp.bitmap != NULL); }
void __init test_basics(void) { struct msi_bitmap bmp; int i, size = 512; /* Can't allocate a bitmap of 0 irqs */ check(msi_bitmap_alloc(&bmp, 0, NULL) != 0); /* of_node may be NULL */ check(0 == msi_bitmap_alloc(&bmp, size, NULL)); /* Should all be free by default */ check(0 == bitmap_find_free_region(bmp.bitmap, size, get_count_order(size))); bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); /* With no node, there's no msi-available-ranges, so expect > 0 */ check(msi_bitmap_reserve_dt_hwirqs(&bmp) > 0); /* Should all still be free */ check(0 == bitmap_find_free_region(bmp.bitmap, size, get_count_order(size))); bitmap_release_region(bmp.bitmap, 0, get_count_order(size)); /* Check we can fill it up and then no more */ for (i = 0; i < size; i++) check(msi_bitmap_alloc_hwirqs(&bmp, 1) >= 0); check(msi_bitmap_alloc_hwirqs(&bmp, 1) < 0); /* Should all be allocated */ check(bitmap_find_free_region(bmp.bitmap, size, 0) < 0); /* And if we free one we can then allocate another */ msi_bitmap_free_hwirqs(&bmp, size / 2, 1); check(msi_bitmap_alloc_hwirqs(&bmp, 1) == size / 2); /* Check we get a naturally aligned offset */ check(msi_bitmap_alloc_hwirqs(&bmp, 2) % 2 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 4) % 4 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 8) % 8 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 9) % 16 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 3) % 4 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 7) % 8 == 0); check(msi_bitmap_alloc_hwirqs(&bmp, 121) % 128 == 0); msi_bitmap_free(&bmp); /* Clients may check bitmap == NULL for "not-allocated" */ check(bmp.bitmap == NULL); kfree(bmp.bitmap); }
static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { int int_no = -ENOMEM; unsigned int virq; struct msi_msg msg; struct msi_desc *entry; struct ppc4xx_msi *msi_data = &ppc4xx_msi; dev_dbg(&dev->dev, "PCIE-MSI:%s called. vec %x type %d\n", __func__, nvec, type); if (type == PCI_CAP_ID_MSIX) pr_debug("ppc4xx msi: MSI-X untested, trying anyway.\n"); msi_data->msi_virqs = kmalloc((msi_irqs) * sizeof(int), GFP_KERNEL); if (!msi_data->msi_virqs) return -ENOMEM; for_each_pci_msi_entry(entry, dev) { int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); if (int_no >= 0) break; if (int_no < 0) { pr_debug("%s: fail allocating msi interrupt\n", __func__); } virq = irq_of_parse_and_map(msi_data->msi_dev, int_no); if (virq == NO_IRQ) { dev_err(&dev->dev, "%s: fail mapping irq\n", __func__); msi_bitmap_free_hwirqs(&msi_data->bitmap, int_no, 1); return -ENOSPC; } dev_dbg(&dev->dev, "%s: virq = %d\n", __func__, virq); /* Setup msi address space */ msg.address_hi = msi_data->msi_addr_hi; msg.address_lo = msi_data->msi_addr_lo; irq_set_msi_desc(virq, entry); msg.data = int_no; pci_write_msi_msg(virq, &msg); }