Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b912c10 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Greg Kroah-Hartman
Browse files

msi: Kill the msi_desc array.



We need to be able to get from an irq number to a struct msi_desc.
The msi_desc array in msi.c had several short comings the big one was
that it could not be used outside of msi.c.  Using irq_data in struct
irq_desc almost worked except on some architectures irq_data needs to
be used for something else.

So this patch adds a msi_desc pointer to irq_desc, adds the appropriate
wrappers and changes all of the msi code to use them.

The dynamic_irq_init/cleanup code was tweaked to ensure the new
field is left in a well defined state.

Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Acked-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 1c659d61
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
	struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);

	entry = get_irq_data(irq);
	entry = get_irq_msi(irq);
	if (!entry->msi_attrib.is_64)
		return -EINVAL;

+21 −23
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@
#include "pci.h"
#include "msi.h"

static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
static struct kmem_cache* msi_cachep;

static int pci_msi_enable = 1;
@@ -43,7 +42,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
{
	struct msi_desc *entry;

	entry = msi_desc[irq];
	entry = get_irq_msi(irq);
	BUG_ON(!entry || !entry->dev);
	switch (entry->msi_attrib.type) {
	case PCI_CAP_ID_MSI:
@@ -73,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)

void read_msi_msg(unsigned int irq, struct msi_msg *msg)
{
	struct msi_desc *entry = get_irq_data(irq);
	struct msi_desc *entry = get_irq_msi(irq);
	switch(entry->msi_attrib.type) {
	case PCI_CAP_ID_MSI:
	{
@@ -112,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)

void write_msi_msg(unsigned int irq, struct msi_msg *msg)
{
	struct msi_desc *entry = get_irq_data(irq);
	struct msi_desc *entry = get_irq_msi(irq);
	switch (entry->msi_attrib.type) {
	case PCI_CAP_ID_MSI:
	{
@@ -208,7 +207,7 @@ static int create_msi_irq(void)
		return -EBUSY;
	}

	set_irq_data(irq, entry);
	set_irq_msi(irq, entry);

	return irq;
}
@@ -217,9 +216,9 @@ static void destroy_msi_irq(unsigned int irq)
{
	struct msi_desc *entry;

	entry = get_irq_data(irq);
	entry = get_irq_msi(irq);
	set_irq_chip(irq, NULL);
	set_irq_data(irq, NULL);
	set_irq_msi(irq, NULL);
	destroy_irq(irq);
	kmem_cache_free(msi_cachep, entry);
}
@@ -360,10 +359,10 @@ static int __pci_save_msix_state(struct pci_dev *dev)
	while (head != tail) {
		struct msi_desc *entry;

		entry = msi_desc[irq];
		entry = get_irq_msi(irq);
		read_msi_msg(irq, &entry->msg_save);

		tail = msi_desc[irq]->link.tail;
		tail = entry->link.tail;
		irq = tail;
	}

@@ -410,10 +409,10 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
	/* route the table */
	irq = head = dev->first_msi_irq;
	while (head != tail) {
		entry = msi_desc[irq];
		entry = get_irq_msi(irq);
		write_msi_msg(irq, &entry->msg_save);

		tail = msi_desc[irq]->link.tail;
		tail = entry->link.tail;
		irq = tail;
	}

@@ -451,7 +450,7 @@ static int msi_capability_init(struct pci_dev *dev)
	if (irq < 0)
		return irq;

	entry = get_irq_data(irq);
	entry = get_irq_msi(irq);
	entry->link.head = irq;
	entry->link.tail = irq;
	entry->msi_attrib.type = PCI_CAP_ID_MSI;
@@ -486,7 +485,7 @@ static int msi_capability_init(struct pci_dev *dev)
	}

	dev->first_msi_irq = irq;
	msi_desc[irq] = entry;
	set_irq_msi(irq, entry);
	/* Set MSI enabled bits	 */
	enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);

@@ -535,7 +534,7 @@ static int msix_capability_init(struct pci_dev *dev,
		if (irq < 0)
			break;

		entry = get_irq_data(irq);
		entry = get_irq_msi(irq);
 		j = entries[i].entry;
 		entries[i].vector = irq;
		entry->msi_attrib.type = PCI_CAP_ID_MSIX;
@@ -565,7 +564,7 @@ static int msix_capability_init(struct pci_dev *dev,
			break;
		}

		msi_desc[irq] = entry;
		set_irq_msi(irq, entry);
	}
	if (i != nvec) {
		int avail = i - 1;
@@ -682,7 +681,7 @@ void pci_disable_msi(struct pci_dev* dev)

	disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);

	entry = msi_desc[dev->first_msi_irq];
	entry = get_irq_msi(dev->first_msi_irq);
	if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
		return;
	}
@@ -709,7 +708,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)

	arch_teardown_msi_irq(irq);

	entry = msi_desc[irq];
	entry = get_irq_msi(irq);
	if (!entry || entry->dev != dev) {
		return -EINVAL;
	}
@@ -717,10 +716,9 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
	entry_nr = entry->msi_attrib.entry_nr;
	head = entry->link.head;
	base = entry->mask_base;
	msi_desc[entry->link.head]->link.tail = entry->link.tail;
	msi_desc[entry->link.tail]->link.head = entry->link.head;
	get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
	get_irq_msi(entry->link.tail)->link.head = entry->link.head;
	entry->dev = NULL;
	msi_desc[irq] = NULL;

	destroy_msi_irq(irq);

@@ -821,7 +819,7 @@ void pci_disable_msix(struct pci_dev* dev)

	irq = head = dev->first_msi_irq;
	while (head != tail) {
		tail = msi_desc[irq]->link.tail;
		tail = get_irq_msi(irq)->link.tail;
		if (irq_has_action(irq))
			warning = 1;
		else if (irq != head)	/* Release MSI-X irq */
@@ -867,8 +865,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)

		irq = head = dev->first_msi_irq;
		while (head != tail) {
			tail = msi_desc[irq]->link.tail;
			base = msi_desc[irq]->mask_base;
			tail = get_irq_msi(irq)->link.tail;
			base = get_irq_msi(irq)->mask_base;
			if (irq_has_action(irq))
				warning = 1;
			else if (irq != head) /* Release MSI-X irq */
+4 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq,
#define IRQ_MOVE_PENDING	0x40000000	/* need to re-target IRQ destination */

struct proc_dir_entry;
struct msi_desc;

/**
 * struct irq_chip - hardware interrupt chip descriptor
@@ -148,6 +149,7 @@ struct irq_chip {
struct irq_desc {
	irq_flow_handler_t	handle_irq;
	struct irq_chip		*chip;
	struct msi_desc		*msi_desc;
	void			*handler_data;
	void			*chip_data;
	struct irqaction	*action;	/* IRQ action list */
@@ -373,10 +375,12 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
extern int set_irq_data(unsigned int irq, void *data);
extern int set_irq_chip_data(unsigned int irq, void *data);
extern int set_irq_type(unsigned int irq, unsigned int type);
extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);

#define get_irq_chip(irq)	(irq_desc[irq].chip)
#define get_irq_chip_data(irq)	(irq_desc[irq].chip_data)
#define get_irq_data(irq)	(irq_desc[irq].handler_data)
#define get_irq_msi(irq)	(irq_desc[irq].msi_desc)

#endif /* CONFIG_GENERIC_HARDIRQS */

+28 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ void dynamic_irq_init(unsigned int irq)
	desc->chip = &no_irq_chip;
	desc->handle_irq = handle_bad_irq;
	desc->depth = 1;
	desc->msi_desc = NULL;
	desc->handler_data = NULL;
	desc->chip_data = NULL;
	desc->action = NULL;
@@ -74,6 +75,9 @@ void dynamic_irq_cleanup(unsigned int irq)
		WARN_ON(1);
		return;
	}
	desc->msi_desc = NULL;
	desc->handler_data = NULL;
	desc->chip_data = NULL;
	desc->handle_irq = handle_bad_irq;
	desc->chip = &no_irq_chip;
	spin_unlock_irqrestore(&desc->lock, flags);
@@ -161,6 +165,30 @@ int set_irq_data(unsigned int irq, void *data)
}
EXPORT_SYMBOL(set_irq_data);

/**
 *	set_irq_data - set irq type data for an irq
 *	@irq:	Interrupt number
 *	@data:	Pointer to interrupt specific data
 *
 *	Set the hardware irq controller data for an irq
 */
int set_irq_msi(unsigned int irq, struct msi_desc *entry)
{
	struct irq_desc *desc;
	unsigned long flags;

	if (irq >= NR_IRQS) {
		printk(KERN_ERR
		       "Trying to install msi data for IRQ%d\n", irq);
		return -EINVAL;
	}
	desc = irq_desc + irq;
	spin_lock_irqsave(&desc->lock, flags);
	desc->msi_desc = entry;
	spin_unlock_irqrestore(&desc->lock, flags);
	return 0;
}

/**
 *	set_irq_chip_data - set irq chip data for an irq
 *	@irq:	Interrupt number