Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion arch/powerpc/platforms/powernv/pci-ioda.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ static int __pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
return -ENXIO;

/* Force 32-bit MSI on some broken devices */
if (dev->no_64bit_msi)
if (dev->msi_addr_mask < DMA_BIT_MASK(64))
is_64 = 0;

/* Assign XIVE to PE */
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/platforms/pseries/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ static int rtas_prepare_msi_irqs(struct pci_dev *pdev, int nvec_in, int type,
*/
again:
if (type == PCI_CAP_ID_MSI) {
if (pdev->no_64bit_msi) {
if (pdev->msi_addr_mask < DMA_BIT_MASK(64)) {
rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec);
if (rc < 0) {
/*
Expand All @@ -409,7 +409,7 @@ static int rtas_prepare_msi_irqs(struct pci_dev *pdev, int nvec_in, int type,
if (use_32bit_msi_hack && rc > 0)
rtas_hack_32bit_msi_gen2(pdev);
} else {
if (pdev->no_64bit_msi)
if (pdev->msi_addr_mask < DMA_BIT_MASK(64))
rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSIX_FN, nvec);
else
rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/radeon/radeon_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,7 @@ int radeon_device_init(struct radeon_device *rdev,
pr_warn("radeon: No suitable DMA available\n");
return r;
}
rdev->pdev->msi_addr_mask = DMA_BIT_MASK(dma_bits);
rdev->need_swiotlb = drm_need_swiotlb(dma_bits);

/* Registers mapping */
Expand Down
10 changes: 0 additions & 10 deletions drivers/gpu/drm/radeon/radeon_irq_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,6 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
if (rdev->flags & RADEON_IS_AGP)
return false;

/*
* Older chips have a HW limitation, they can only generate 40 bits
* of address for "64-bit" MSIs which breaks on some platforms, notably
* IBM POWER servers, so we limit them
*/
if (rdev->family < CHIP_BONAIRE) {
dev_info(rdev->dev, "radeon: MSI limited to 32-bit\n");
rdev->pdev->no_64bit_msi = 1;
}

/* force MSI on */
if (radeon_msi == 1)
return true;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

#ifdef CONFIG_PPC64
/* Ensure MSI/MSI-X interrupts lie within addressable physical memory */
pdev->no_64bit_msi = 1;
pdev->msi_addr_mask = DMA_BIT_MASK(32);
#endif

err = ionic_setup_one(ionic);
Expand Down
11 changes: 7 additions & 4 deletions drivers/pci/msi/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,17 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
static int msi_verify_entries(struct pci_dev *dev)
{
struct msi_desc *entry;
u64 address;

if (!dev->no_64bit_msi)
if (dev->msi_addr_mask == DMA_BIT_MASK(64))
return 0;

msi_for_each_desc(entry, &dev->dev, MSI_DESC_ALL) {
if (entry->msg.address_hi) {
pci_err(dev, "arch assigned 64-bit MSI address %#x%08x but device only supports 32 bits\n",
entry->msg.address_hi, entry->msg.address_lo);
address = (u64)entry->msg.address_hi << 32 |
entry->msg.address_lo;
if (address & ~dev->msi_addr_mask) {
pci_err(dev, "arch assigned 64-bit MSI address %#llx above device MSI address mask %#llx\n",
address, dev->msi_addr_mask);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/pci/msi/pcidev_msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void pci_msi_init(struct pci_dev *dev)
}

if (!(ctrl & PCI_MSI_FLAGS_64BIT))
dev->no_64bit_msi = 1;
dev->msi_addr_mask = DMA_BIT_MASK(32);
}

void pci_msix_init(struct pci_dev *dev)
Expand Down
7 changes: 7 additions & 0 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,13 @@ int pci_setup_device(struct pci_dev *dev)
*/
dev->dma_mask = 0xffffffff;

/*
* Assume 64-bit addresses for MSI initially. Will be changed to 32-bit
* if MSI (rather than MSI-X) capability does not have
* PCI_MSI_FLAGS_64BIT. Can also be overridden by driver.
*/
dev->msi_addr_mask = DMA_BIT_MASK(64);

dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
dev->bus->number, PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
Expand Down
8 changes: 7 additions & 1 deletion include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,13 @@ struct pci_dev {
0xffffffff. You only need to change
this if your device has broken DMA
or supports 64-bit transfers. */
u64 msi_addr_mask; /* Mask of the bits of bus address for
MSI that this device implements.
Normally set based on device
capabilities. You only need to
change this if your device claims
to support 64-bit MSI but implements
fewer than 64 address bits. */

struct device_dma_parameters dma_parms;

Expand Down Expand Up @@ -442,7 +449,6 @@ struct pci_dev {

unsigned int is_busmaster:1; /* Is busmaster */
unsigned int no_msi:1; /* May not use MSI */
unsigned int no_64bit_msi:1; /* May only use 32-bit MSIs */
unsigned int block_cfg_access:1; /* Config space access blocked */
unsigned int broken_parity_status:1; /* Generates false positive parity */
unsigned int irq_reroute_variant:2; /* Needs IRQ rerouting variant */
Expand Down
10 changes: 5 additions & 5 deletions sound/hda/controllers/intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1903,11 +1903,6 @@ static int azx_first_init(struct azx *chip)
chip->gts_present = true;
#endif

if (chip->msi && chip->driver_caps & AZX_DCAPS_NO_MSI64) {
dev_dbg(card->dev, "Disabling 64bit MSI\n");
pci->no_64bit_msi = true;
}

pci_set_master(pci);

gcap = azx_readw(chip, GCAP);
Expand Down Expand Up @@ -1958,6 +1953,11 @@ static int azx_first_init(struct azx *chip)
dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32));
dma_set_max_seg_size(&pci->dev, UINT_MAX);

if (chip->msi && chip->driver_caps & AZX_DCAPS_NO_MSI64) {
dev_dbg(card->dev, "Restricting MSI to %u-bit\n", dma_bits);
pci->msi_addr_mask = DMA_BIT_MASK(dma_bits);
}

/* read number of streams from GCAP register instead of using
* hardcoded value
*/
Expand Down