Index: sys/compat/linuxkpi/common/include/linux/pci.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/pci.h +++ sys/compat/linuxkpi/common/include/linux/pci.h @@ -702,6 +702,23 @@ } } +static inline void +linux_pci_save_state(struct pci_dev *pdev) +{ + + pci_save_state(pdev->dev.bsddev); +} + +static inline void +linux_pci_restore_state(struct pci_dev *pdev) +{ + + pci_restore_state(pdev->dev.bsddev); +} + +#define pci_save_state(dev) linux_pci_save_state(dev) +#define pci_restore_state(dev) linux_pci_restore_state(dev) + #define DEFINE_PCI_DEVICE_TABLE(_table) \ const struct pci_device_id _table[] __devinitdata @@ -1058,4 +1075,78 @@ return (0); } +static inline bool +pci_is_root_bus(struct pci_bus *pbus) +{ + + return (pbus->self == NULL); +} + +struct pci_dev *linuxkpi_pci_get_domain_bus_and_slot(int domain, unsigned int bus, unsigned int devfn); +#define pci_get_domain_bus_and_slot(domain, bus, devfn) \ + linuxkpi_pci_get_domain_bus_and_slot(domain, bus, devfn) + +int linuxkpi_pci_domain_nr(struct pci_bus *bus); +#define pci_domain_nr(bus) linuxkpi_pci_domain_nr(bus) + +static inline int +pci_bus_read_config(struct pci_bus *bus, unsigned int devfn, + int pos, uint32_t *val, int len) +{ + device_t dev; + + dev = pci_find_dbsf(pci_get_domain(bus->self->dev.bsddev), + pci_get_bus(bus->self->dev.bsddev), + PCI_SLOT(devfn), + PCI_FUNC(devfn)); + *val = pci_read_config(dev, pos, len); + return (0); +} + +static inline int +pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, int pos, u16 *val) +{ + return (pci_bus_read_config(bus, devfn, pos, (uint32_t *)val, 2)); +} + +static inline int +pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, int pos, u8 *val) +{ + return (pci_bus_read_config(bus, devfn, pos, (uint32_t *)val, 1)); +} + +static inline int +pci_bus_write_config(struct pci_bus *bus, unsigned int devfn, int pos, + uint32_t val, int size) +{ + device_t dev; + + dev = pci_find_dbsf(pci_get_domain(bus->self->dev.bsddev), + pci_get_bus(bus->self->dev.bsddev), + PCI_SLOT(devfn), + PCI_FUNC(devfn)); + pci_write_config(dev, pos, val, size); + return (0); +} + +static inline int +pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, int pos, + uint8_t val) +{ + return (pci_bus_write_config(bus, devfn, pos, val, 1)); +} + +static inline int +pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, int pos, + uint16_t val) +{ + return (pci_bus_write_config(bus, devfn, pos, val, 2)); +} + +void linuxkpi_pci_dev_put(struct pci_dev *pdev); +#define pci_dev_put(pdev) linuxkpi_pci_dev_put(pdev) + +struct pci_dev *linuxkpi_pci_get_class(unsigned int class, struct pci_dev *from); +#define pci_get_class(class, from) linuxkpi_pci_get_class(class, from) + #endif /* _LINUX_PCI_H_ */ Index: sys/compat/linuxkpi/common/src/linux_pci.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_pci.c +++ sys/compat/linuxkpi/common/src/linux_pci.c @@ -69,6 +69,9 @@ #include "backlight_if.h" +/* Undef the linux function macro defined in linux/pci.h */ +#undef pci_get_class + static device_probe_t linux_pci_probe; static device_attach_t linux_pci_attach; static device_detach_t linux_pci_detach; @@ -209,6 +212,66 @@ return (NULL); } +struct pci_dev * +linuxkpi_pci_get_class(unsigned int class, struct pci_dev *from) +{ + device_t dev; + device_t devfrom = NULL; + struct pci_dev *pdev; + struct pci_bus *pbus; + + if (from != NULL) + devfrom = from->dev.bsddev; + + dev = pci_find_class_from(class >> 16, (class >> 8) & 0xFF, devfrom); + if (dev == NULL) + return (NULL); + + pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO); + pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev)); + pdev->vendor = pci_get_vendor(dev); + pdev->device = pci_get_device(dev); + pdev->dev.bsddev = dev; + pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK|M_ZERO); + pbus->self = pdev; + pdev->bus = pbus; + pdev->bus->number = pci_get_bus(dev); + pdev->bus->domain = pci_get_domain(dev); + return (pdev); +} + +struct pci_dev * +linuxkpi_pci_get_domain_bus_and_slot(int domain, unsigned int bus, + unsigned int devfn) +{ + device_t dev; + struct pci_dev *pdev; + struct pci_bus *pbus; + + dev = pci_find_dbsf(domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + if (dev == NULL) + return (NULL); + + pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO); + pdev->devfn = devfn; + pdev->vendor = pci_get_vendor(dev); + pdev->device = pci_get_device(dev); + pdev->dev.bsddev = dev; + pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK|M_ZERO); + pbus->self = pdev; + pdev->bus = pbus; + pdev->bus->number = pci_get_bus(dev); + pdev->bus->domain = pci_get_domain(dev); + return (pdev); +} + +int +linuxkpi_pci_domain_nr(struct pci_bus *pbus) +{ + + return (pci_get_domain(pbus->self->dev.bsddev)); +} + static int linux_pci_probe(device_t dev) { @@ -347,6 +410,18 @@ return (0); } +void +linuxkpi_pci_dev_put(struct pci_dev *pdev) +{ + if (pdev == NULL) + return; + + MPASS(pdev->bus); + MPASS(pdev->bus->self == pdev); + free(pdev->bus, M_DEVBUF); + free(pdev, M_DEVBUF); +} + static int linux_pci_suspend(device_t dev) { Index: sys/dev/mlx4/mlx4_core/mlx4_main.c =================================================================== --- sys/dev/mlx4/mlx4_core/mlx4_main.c +++ sys/dev/mlx4/mlx4_core/mlx4_main.c @@ -3781,7 +3781,7 @@ return ret; } else { device_set_desc(pdev->dev.bsddev, mlx4_description); - pci_save_state(pdev->dev.bsddev); + pci_save_state(pdev); } snprintf(dev->fw_str, sizeof(dev->fw_str), "%d.%d.%d", Index: sys/dev/mlx5/mlx5_core/mlx5_main.c =================================================================== --- sys/dev/mlx5/mlx5_core/mlx5_main.c +++ sys/dev/mlx5/mlx5_core/mlx5_main.c @@ -1643,7 +1643,7 @@ } #endif - pci_save_state(bsddev); + pci_save_state(pdev); return 0; clean_health: @@ -1713,8 +1713,8 @@ } pci_set_master(pdev); pci_set_powerstate(pdev->dev.bsddev, PCI_POWERSTATE_D0); - pci_restore_state(pdev->dev.bsddev); - pci_save_state(pdev->dev.bsddev); + pci_restore_state(pdev); + pci_save_state(pdev); return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; }