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 @@ -97,10 +97,10 @@ #define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 #define PCI_SUBDEVICE_ID_QEMU 0x1100 -#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) -#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) -#define PCI_FUNC(devfn) ((devfn) & 0x07) -#define PCI_BUS_NUM(devfn) (((devfn) >> 8) & 0xff) +#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 8) | (func)) +#define PCI_SLOT(devfn) (((devfn) >> 8) & 0x1f) +#define PCI_FUNC(devfn) ((devfn) & 0xff) +#define PCI_BUS_NUM(devfn) (((devfn) >> 16) & 0xff) #define PCI_VDEVICE(_vendor, _device) \ .vendor = PCI_VENDOR_ID_##_vendor, .device = (_device), \ @@ -702,6 +702,23 @@ } } +static inline void +lkpi_pci_save_state(struct pci_dev *pdev) +{ + + pci_save_state(pdev->dev.bsddev); +} + +static inline void +lkpi_pci_restore_state(struct pci_dev *pdev) +{ + + pci_restore_state(pdev->dev.bsddev); +} + +#define pci_save_state(dev) lkpi_pci_save_state(dev) +#define pci_restore_state(dev) lkpi_pci_restore_state(dev) + #define DEFINE_PCI_DEVICE_TABLE(_table) \ const struct pci_device_id _table[] __devinitdata @@ -1058,4 +1075,90 @@ return (0); } +static inline bool +pci_is_root_bus(struct pci_bus *pbus) +{ + + return (pbus->self == NULL); +} + +struct pci_dev *lkpi_pci_get_domain_bus_and_slot(int domain, + unsigned int bus, unsigned int devfn); +#define pci_get_domain_bus_and_slot(domain, bus, devfn) \ + lkpi_pci_get_domain_bus_and_slot(domain, bus, devfn) + +static inline int +pci_domain_nr(struct pci_bus *pbus) +{ + + return (pci_get_domain(pbus->self->dev.bsddev)); +} + +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) +{ + uint32_t tmp; + int ret; + + ret = pci_bus_read_config(bus, devfn, pos, &tmp, 2); + *val = (u16)tmp; + return (ret); +} + +static inline int +pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, int pos, u8 *val) +{ + uint32_t tmp; + int ret; + + ret = pci_bus_read_config(bus, devfn, pos, &tmp, 1); + *val = (u8)tmp; + return (ret); +} + +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)); +} + +struct pci_dev *lkpi_pci_get_class(unsigned int class, struct pci_dev *from); +#define pci_get_class(class, from) lkpi_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,67 @@ return (NULL); } +static void +lkpifill_pci_dev(device_t dev, struct pci_dev *pdev) +{ + + 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->class = pci_get_class(dev); + pdev->revision = pci_get_revid(dev); + pdev->dev.bsddev = dev; + pdev->bus->self = pdev; + pdev->bus->number = pci_get_bus(dev); + pdev->bus->domain = pci_get_domain(dev); +} + +static struct pci_dev * +lkpinew_pci_dev(device_t dev) +{ + struct pci_dev *pdev; + struct pci_bus *pbus; + + pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO); + pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK|M_ZERO); + pdev->bus = pbus; + lkpifill_pci_dev(dev, pdev); + return (pdev); +} + +struct pci_dev * +lkpi_pci_get_class(unsigned int class, struct pci_dev *from) +{ + device_t dev; + device_t devfrom = NULL; + struct pci_dev *pdev; + + if (from != NULL) + devfrom = from->dev.bsddev; + + dev = pci_find_class_from(class >> 16, (class >> 8) & 0xFF, devfrom); + if (dev == NULL) + return (NULL); + + pdev = lkpinew_pci_dev(dev); + return (pdev); +} + +struct pci_dev * +lkpi_pci_get_domain_bus_and_slot(int domain, unsigned int bus, + unsigned int devfn) +{ + device_t dev; + struct pci_dev *pdev; + + dev = pci_find_dbsf(domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + if (dev == NULL) + return (NULL); + + pdev = lkpinew_pci_dev(dev); + return (pdev); +} + static int linux_pci_probe(device_t dev) { @@ -244,7 +308,6 @@ const struct pci_device_id *id, struct pci_dev *pdev) { struct resource_list_entry *rle; - struct pci_bus *pbus; struct pci_devinfo *dinfo; device_t parent; int error; @@ -259,16 +322,12 @@ dinfo = device_get_ivars(dev); } + pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO); + lkpifill_pci_dev(dev, pdev); pdev->dev.parent = &linux_root_device; - pdev->dev.bsddev = dev; INIT_LIST_HEAD(&pdev->dev.irqents); - pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev)); - pdev->device = dinfo->cfg.device; - pdev->vendor = dinfo->cfg.vendor; pdev->subsystem_vendor = dinfo->cfg.subvendor; pdev->subsystem_device = dinfo->cfg.subdevice; - pdev->class = pci_get_class(dev); - pdev->revision = pci_get_revid(dev); pdev->pdrv = pdrv; kobject_init(&pdev->dev.kobj, &linux_dev_ktype); kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev)); @@ -285,11 +344,6 @@ goto out_dma_init; TAILQ_INIT(&pdev->mmio); - pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK | M_ZERO); - pbus->self = pdev; - pbus->number = pci_get_bus(dev); - pbus->domain = pci_get_domain(dev); - pdev->bus = pbus; spin_lock(&pci_lock); list_add(&pdev->links, &pci_devices); 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; }