Skip to content

Commit

Permalink
powerpc/pseries: Fix endian issues in MSI code
Browse files Browse the repository at this point in the history
The MSI code is miscalculating quotas in little endian mode.
Add required byteswaps to fix this.

Before we claimed a quota of 65536, after the patch we
see the correct value of 256.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Anton Blanchard authored and Benjamin Herrenschmidt committed Dec 13, 2013
1 parent 5091f0c commit 8d15315
Showing 1 changed file with 15 additions and 13 deletions.
28 changes: 15 additions & 13 deletions arch/powerpc/platforms/pseries/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,27 +130,29 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
{
struct device_node *dn;
struct pci_dn *pdn;
const u32 *req_msi;
const __be32 *p;
u32 req_msi;

pdn = pci_get_pdn(pdev);
if (!pdn)
return -ENODEV;

dn = pdn->node;

req_msi = of_get_property(dn, prop_name, NULL);
if (!req_msi) {
p = of_get_property(dn, prop_name, NULL);
if (!p) {
pr_debug("rtas_msi: No %s on %s\n", prop_name, dn->full_name);
return -ENOENT;
}

if (*req_msi < nvec) {
req_msi = be32_to_cpup(p);
if (req_msi < nvec) {
pr_debug("rtas_msi: %s requests < %d MSIs\n", prop_name, nvec);

if (*req_msi == 0) /* Be paranoid */
if (req_msi == 0) /* Be paranoid */
return -ENOSPC;

return *req_msi;
return req_msi;
}

return 0;
Expand All @@ -171,15 +173,15 @@ static int check_req_msix(struct pci_dev *pdev, int nvec)
static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
{
struct device_node *dn;
const u32 *p;
const __be32 *p;

dn = of_node_get(pci_device_to_OF_node(dev));
while (dn) {
p = of_get_property(dn, "ibm,pe-total-#msi", NULL);
if (p) {
pr_debug("rtas_msi: found prop on dn %s\n",
dn->full_name);
*total = *p;
*total = be32_to_cpup(p);
return dn;
}

Expand Down Expand Up @@ -232,13 +234,13 @@ struct msi_counts {
static void *count_non_bridge_devices(struct device_node *dn, void *data)
{
struct msi_counts *counts = data;
const u32 *p;
const __be32 *p;
u32 class;

pr_debug("rtas_msi: counting %s\n", dn->full_name);

p = of_get_property(dn, "class-code", NULL);
class = p ? *p : 0;
class = p ? be32_to_cpup(p) : 0;

if ((class >> 8) != PCI_CLASS_BRIDGE_PCI)
counts->num_devices++;
Expand All @@ -249,7 +251,7 @@ static void *count_non_bridge_devices(struct device_node *dn, void *data)
static void *count_spare_msis(struct device_node *dn, void *data)
{
struct msi_counts *counts = data;
const u32 *p;
const __be32 *p;
int req;

if (dn == counts->requestor)
Expand All @@ -260,11 +262,11 @@ static void *count_spare_msis(struct device_node *dn, void *data)
req = 0;
p = of_get_property(dn, "ibm,req#msi", NULL);
if (p)
req = *p;
req = be32_to_cpup(p);

p = of_get_property(dn, "ibm,req#msi-x", NULL);
if (p)
req = max(req, (int)*p);
req = max(req, (int)be32_to_cpup(p));
}

if (req < counts->quota)
Expand Down

0 comments on commit 8d15315

Please sign in to comment.