diff -r 7da7fbb2005c -r 2bbab0c39a06 sys/compat/linuxkpi/common/include/linux/pci.h --- a/sys/compat/linuxkpi/common/include/linux/pci.h Mon Apr 20 15:07:43 2020 -0700 +++ b/sys/compat/linuxkpi/common/include/linux/pci.h Tue Apr 21 15:19:04 2020 -0700 @@ -956,12 +956,12 @@ pcie_get_width_cap(struct pci_dev *dev) /* * The following functions can be used to attach/detach the LinuxKPI's - * PCI device runtime. The only requirement is that the softc of the - * passed device starts with a pci_dev structure as defined by this - * file. The pci_driver and pci_device_id pointer is allowed to be - * NULL. + * PCI device runtime. If the softc of the passed device does not start with + * a pci_dev structure then the address of the pci_dev must be provided. + * The pci_driver and pci_device_id pointer is allowed to be NULL. */ -extern int linux_pci_attach_device(device_t, struct pci_driver *, const struct pci_device_id *); -extern int linux_pci_detach_device(device_t); +extern int linux_pci_attach_device(device_t, struct pci_driver *, + const struct pci_device_id *, struct pci_dev *); +extern int linux_pci_detach_device(device_t, struct pci_dev *); #endif /* _LINUX_PCI_H_ */ diff -r 7da7fbb2005c -r 2bbab0c39a06 sys/compat/linuxkpi/common/src/linux_pci.c --- a/sys/compat/linuxkpi/common/src/linux_pci.c Mon Apr 20 15:07:43 2020 -0700 +++ b/sys/compat/linuxkpi/common/src/linux_pci.c Tue Apr 21 15:19:04 2020 -0700 @@ -220,23 +220,23 @@ linux_pci_attach(device_t dev) MPASS(pdrv != NULL); - return (linux_pci_attach_device(dev, pdrv, id)); + return (linux_pci_attach_device(dev, pdrv, id, NULL)); } int linux_pci_attach_device(device_t dev, struct pci_driver *pdrv, - const struct pci_device_id *id) + const struct pci_device_id *id, struct pci_dev *pdev) { struct resource_list_entry *rle; struct pci_bus *pbus; - struct pci_dev *pdev; struct pci_devinfo *dinfo; device_t parent; int error; linux_set_current(curthread); - pdev = device_get_softc(dev); + if (pdev == NULL) + pdev = device_get_softc(dev); parent = device_get_parent(dev); if (pdrv != NULL && pdrv->isdrm) { dinfo = device_get_ivars(parent); @@ -302,16 +302,16 @@ static int linux_pci_detach(device_t dev) { - return (linux_pci_detach_device(dev)); + return (linux_pci_detach_device(dev, NULL)); } int -linux_pci_detach_device(device_t dev) +linux_pci_detach_device(device_t dev, struct pci_dev *pdev) { - struct pci_dev *pdev; linux_set_current(curthread); - pdev = device_get_softc(dev); + if (pdev == NULL) + pdev = device_get_softc(dev); if (pdev->pdrv != NULL) pdev->pdrv->remove(pdev);