Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/src/linux_pci.c
/*- | /*- | ||||
* Copyright (c) 2015-2016 Mellanox Technologies, Ltd. | * Copyright (c) 2015-2016 Mellanox Technologies, Ltd. | ||||
* All rights reserved. | * All rights reserved. | ||||
* Copyright (c) 2020-2021 The FreeBSD Foundation | |||||
* | * | ||||
* Portions of this software were developed by Björn Zeeb | |||||
* under sponsorship from the FreeBSD Foundation. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice unmodified, this list of conditions, and the following | * notice unmodified, this list of conditions, and the following | ||||
* disclaimer. | * disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
* notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
▲ Show 20 Lines • Show All 212 Lines • ▼ Show 20 Lines | lkpifill_pci_dev(device_t dev, struct pci_dev *pdev) | ||||
pdev->class = pci_get_class(dev); | pdev->class = pci_get_class(dev); | ||||
pdev->revision = pci_get_revid(dev); | pdev->revision = pci_get_revid(dev); | ||||
pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO); | pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO); | ||||
pdev->bus->self = pdev; | pdev->bus->self = pdev; | ||||
pdev->bus->number = pci_get_bus(dev); | pdev->bus->number = pci_get_bus(dev); | ||||
pdev->bus->domain = pci_get_domain(dev); | pdev->bus->domain = pci_get_domain(dev); | ||||
pdev->dev.bsddev = dev; | pdev->dev.bsddev = dev; | ||||
pdev->dev.parent = &linux_root_device; | pdev->dev.parent = &linux_root_device; | ||||
pdev->dev.release = lkpi_pci_dev_release; | |||||
INIT_LIST_HEAD(&pdev->dev.irqents); | INIT_LIST_HEAD(&pdev->dev.irqents); | ||||
kobject_init(&pdev->dev.kobj, &linux_dev_ktype); | kobject_init(&pdev->dev.kobj, &linux_dev_ktype); | ||||
kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev)); | kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev)); | ||||
kobject_add(&pdev->dev.kobj, &linux_root_device.kobj, | kobject_add(&pdev->dev.kobj, &linux_root_device.kobj, | ||||
kobject_name(&pdev->dev.kobj)); | kobject_name(&pdev->dev.kobj)); | ||||
spin_lock_init(&pdev->dev.devres_lock); | spin_lock_init(&pdev->dev.devres_lock); | ||||
INIT_LIST_HEAD(&pdev->dev.devres_head); | INIT_LIST_HEAD(&pdev->dev.devres_head); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | lkpi_pci_get_domain_bus_and_slot(int domain, unsigned int bus, | ||||
dev = pci_find_dbsf(domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); | dev = pci_find_dbsf(domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); | ||||
if (dev == NULL) | if (dev == NULL) | ||||
return (NULL); | return (NULL); | ||||
pdev = lkpinew_pci_dev(dev); | pdev = lkpinew_pci_dev(dev); | ||||
return (pdev); | return (pdev); | ||||
} | } | ||||
static void | |||||
lkpi_pci_dev_release(struct device *dev) | |||||
{ | |||||
lkpi_devres_release_free_list(dev); | |||||
spin_lock_destroy(&dev->devres_lock); | |||||
} | |||||
static int | static int | ||||
linux_pci_probe(device_t dev) | linux_pci_probe(device_t dev) | ||||
{ | { | ||||
const struct pci_device_id *id; | const struct pci_device_id *id; | ||||
struct pci_driver *pdrv; | struct pci_driver *pdrv; | ||||
if ((pdrv = linux_pci_find(dev, &id)) == NULL) | if ((pdrv = linux_pci_find(dev, &id)) == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
Show All 37 Lines | linux_pci_attach_device(device_t dev, struct pci_driver *pdrv, | ||||
if (isdrm) { | if (isdrm) { | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
dinfo = device_get_ivars(parent); | dinfo = device_get_ivars(parent); | ||||
device_set_ivars(dev, dinfo); | device_set_ivars(dev, dinfo); | ||||
} | } | ||||
lkpifill_pci_dev(dev, pdev); | lkpifill_pci_dev(dev, pdev); | ||||
if (isdrm) | if (isdrm) | ||||
hselasky: Factor this line into the lkpifill_pci_dev() function ? | |||||
Done Inline ActionsDone. I just need to find the other change adding the 2nd case of this assignment and sort it there as well then. bz: Done. I just need to find the other change adding the 2nd case of this assignment and sort it… | |||||
PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid); | PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid); | ||||
else | else | ||||
PCI_GET_ID(parent, dev, PCI_ID_RID, &rid); | PCI_GET_ID(parent, dev, PCI_ID_RID, &rid); | ||||
pdev->devfn = rid; | pdev->devfn = rid; | ||||
pdev->pdrv = pdrv; | pdev->pdrv = pdrv; | ||||
rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0); | rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0); | ||||
if (rle != NULL) | if (rle != NULL) | ||||
pdev->dev.irq = rle->start; | pdev->dev.irq = rle->start; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | linux_pci_detach_device(struct pci_dev *pdev) | ||||
linux_pdev_dma_uninit(pdev); | linux_pdev_dma_uninit(pdev); | ||||
spin_lock(&pci_lock); | spin_lock(&pci_lock); | ||||
list_del(&pdev->links); | list_del(&pdev->links); | ||||
spin_unlock(&pci_lock); | spin_unlock(&pci_lock); | ||||
put_device(&pdev->dev); | put_device(&pdev->dev); | ||||
return (0); | return (0); | ||||
} | |||||
static int | |||||
lkpi_pci_disable_dev(struct device *dev) | |||||
{ | |||||
(void) pci_disable_io(dev->bsddev, SYS_RES_MEMORY); | |||||
Done Inline ActionsDisable busmaster too? hselasky: Disable busmaster too? | |||||
Done Inline Actionspcim_enable_device() doesn't track that; and not under "enable_io". This is merely the private opposite of pci_enable_device(). bz: pcim_enable_device() doesn't track that; and not under "enable_io". This is merely the… | |||||
(void) pci_disable_io(dev->bsddev, SYS_RES_IOPORT); | |||||
return (0); | |||||
} | |||||
void | |||||
lkpi_pci_devres_release(struct device *dev, void *p) | |||||
{ | |||||
struct pci_devres *dr; | |||||
struct pci_dev *pdev; | |||||
int bar; | |||||
pdev = to_pci_dev(dev); | |||||
dr = p; | |||||
if (pdev->msix_enabled) | |||||
lkpi_pci_disable_msix(pdev); | |||||
if (pdev->msi_enabled) | |||||
lkpi_pci_disable_msi(pdev); | |||||
if (dr->enable_io && lkpi_pci_disable_dev(dev) == 0) | |||||
dr->enable_io = false; | |||||
if (dr->region_mask == 0) | |||||
return; | |||||
for (bar = PCIR_MAX_BAR_0; bar >= 0; bar--) { | |||||
if ((dr->region_mask & (1 << bar)) == 0) | |||||
continue; | |||||
pci_release_region(pdev, bar); | |||||
} | |||||
} | |||||
void | |||||
lkpi_pcim_iomap_table_release(struct device *dev, void *p) | |||||
{ | |||||
struct pcim_iomap_devres *dr; | |||||
struct pci_dev *pdev; | |||||
int bar; | |||||
dr = p; | |||||
pdev = to_pci_dev(dev); | |||||
for (bar = PCIR_MAX_BAR_0; bar >= 0; bar--) { | |||||
if (dr->mmio_table[bar] == NULL) | |||||
continue; | |||||
pci_iounmap(pdev, dr->mmio_table[bar]); | |||||
} | |||||
} | } | ||||
static int | static int | ||||
linux_pci_suspend(device_t dev) | linux_pci_suspend(device_t dev) | ||||
{ | { | ||||
const struct dev_pm_ops *pmops; | const struct dev_pm_ops *pmops; | ||||
struct pm_message pm = { }; | struct pm_message pm = { }; | ||||
struct pci_dev *pdev; | struct pci_dev *pdev; | ||||
▲ Show 20 Lines • Show All 690 Lines • Show Last 20 Lines |
Factor this line into the lkpifill_pci_dev() function ?