svn commit: r351009 - head/sys/compat/linuxkpi/common/include/linux
Cy Schubert
Cy.Schubert at cschubert.com
Wed Aug 14 19:00:55 UTC 2019
In message <201908140936.x7E9aQAc069612 at repo.freebsd.org>, Hans Petter
Selasky
writes:
> Author: hselasky
> Date: Wed Aug 14 09:36:25 2019
> New Revision: 351009
> URL: https://svnweb.freebsd.org/changeset/base/351009
>
> Log:
> Implement pci_enable_msi() and pci_disable_msi() in the LinuxKPI.
> This patch makes the DRM graphics driver in ports usable on aarch64.
>
> Submitted by: Greg V <greg at unrelenting.technology>
> Differential Revision: https://reviews.freebsd.org/D21008
> MFC after: 1 week
> Sponsored by: Mellanox Technologies
>
> Modified:
> head/sys/compat/linuxkpi/common/include/linux/device.h
> head/sys/compat/linuxkpi/common/include/linux/interrupt.h
> head/sys/compat/linuxkpi/common/include/linux/pci.h
>
> Modified: head/sys/compat/linuxkpi/common/include/linux/device.h
> =============================================================================
> =
> --- head/sys/compat/linuxkpi/common/include/linux/device.h Wed Aug 14 06:4
> 1:22 2019 (r351008)
> +++ head/sys/compat/linuxkpi/common/include/linux/device.h Wed Aug 14 09:3
> 6:25 2019 (r351009)
> @@ -110,8 +110,8 @@ struct device {
> void *driver_data;
> unsigned int irq;
> #define LINUX_IRQ_INVALID 65535
> - unsigned int msix;
> - unsigned int msix_max;
> + unsigned int irq_start;
> + unsigned int irq_end;
> const struct attribute_group **groups;
> struct fwnode_handle *fwnode;
>
>
> Modified: head/sys/compat/linuxkpi/common/include/linux/interrupt.h
> =============================================================================
> =
> --- head/sys/compat/linuxkpi/common/include/linux/interrupt.h Wed Aug 14 06:4
> 1:22 2019 (r351008)
> +++ head/sys/compat/linuxkpi/common/include/linux/interrupt.h Wed Aug 14 09:3
> 6:25 2019 (r351009)
> @@ -55,9 +55,11 @@ struct irq_ent {
> static inline int
> linux_irq_rid(struct device *dev, unsigned int irq)
> {
> - if (irq == dev->irq)
> + /* check for MSI- or MSIX- interrupt */
> + if (irq >= dev->irq_start && irq < dev->irq_end)
> + return (irq - dev->irq_start + 1);
> + else
> return (0);
> - return irq - dev->msix + 1;
> }
>
> extern void linux_irq_handler(void *);
>
> Modified: head/sys/compat/linuxkpi/common/include/linux/pci.h
> =============================================================================
> =
> --- head/sys/compat/linuxkpi/common/include/linux/pci.h Wed Aug 14 06:4
> 1:22 2019 (r351008)
> +++ head/sys/compat/linuxkpi/common/include/linux/pci.h Wed Aug 14 09:3
> 6:25 2019 (r351009)
> @@ -228,6 +228,7 @@ struct pci_dev {
> unsigned int devfn;
> uint32_t class;
> uint8_t revision;
> + bool msi_enabled;
> };
>
> static inline struct resource_list_entry *
> @@ -262,7 +263,7 @@ linux_pci_find_irq_dev(unsigned int irq)
> spin_lock(&pci_lock);
> list_for_each_entry(pdev, &pci_devices, links) {
> if (irq == pdev->dev.irq ||
> - (irq >= pdev->dev.msix && irq < pdev->dev.msix_max)) {
> + (irq >= pdev->dev.irq_start && irq < pdev->dev.irq_end)) {
> found = &pdev->dev;
> break;
> }
> @@ -424,10 +425,25 @@ pci_disable_msix(struct pci_dev *pdev)
> * linux_pci_find_irq_dev() does no longer see them by
> * resetting their references to zero:
> */
> - pdev->dev.msix = 0;
> - pdev->dev.msix_max = 0;
> + pdev->dev.irq_start = 0;
> + pdev->dev.irq_end = 0;
> }
>
> +#define pci_disable_msi(pdev) \
> + linux_pci_disable_msi(pdev)
> +
> +static inline void
> +linux_pci_disable_msi(struct pci_dev *pdev)
> +{
> +
> + pci_release_msi(pdev->dev.bsddev);
> +
> + pdev->dev.irq_start = 0;
> + pdev->dev.irq_end = 0;
> + pdev->irq = pdev->dev.irq;
> + pdev->msi_enabled = false;
> +}
> +
> unsigned long pci_resource_start(struct pci_dev *pdev, int bar);
> unsigned long pci_resource_len(struct pci_dev *pdev, int bar);
>
> @@ -562,10 +578,10 @@ pci_enable_msix(struct pci_dev *pdev, struct msix_entr
> return avail;
> }
> rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1);
> - pdev->dev.msix = rle->start;
> - pdev->dev.msix_max = rle->start + avail;
> + pdev->dev.irq_start = rle->start;
> + pdev->dev.irq_end = rle->start + avail;
> for (i = 0; i < nreq; i++)
> - entries[i].vector = pdev->dev.msix + i;
> + entries[i].vector = pdev->dev.irq_start + i;
> return (0);
> }
>
> @@ -593,6 +609,32 @@ pci_enable_msix_range(struct pci_dev *dev, struct msix
> }
> } while (rc);
> return (nvec);
> +}
> +
> +#define pci_enable_msi(pdev) \
> + linux_pci_enable_msi(pdev)
> +
> +static inline int
> +pci_enable_msi(struct pci_dev *pdev)
> +{
> + struct resource_list_entry *rle;
> + int error;
> + int avail;
> +
> + avail = pci_msi_count(pdev->dev.bsddev);
> + if (avail < 1)
> + return -EINVAL;
> +
> + avail = 1; /* this function only enable one MSI IRQ */
> + if ((error = -pci_alloc_msi(pdev->dev.bsddev, &avail)) != 0)
> + return error;
> +
> + rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1);
> + pdev->dev.irq_start = rle->start;
> + pdev->dev.irq_end = rle->start + avail;
> + pdev->irq = rle->start;
> + pdev->msi_enabled = true;
> + return (0);
> }
>
> static inline int
>
John's patch to drm-current-kmod (ports r508877) works! This broke
drm-current-kmod.
--
Cheers,
Cy Schubert <Cy.Schubert at cschubert.com>
FreeBSD UNIX: <cy at FreeBSD.org> Web: http://www.FreeBSD.org
The need of the many outweighs the greed of the few.
More information about the svn-src-all
mailing list