Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: add PCI-X/PCI-Express read control interfaces

This patch introduces an interface to read and write PCI-X / PCI-Express
maximum read byte count values from PCI config space. There is a second
function that returns the maximum _designed_ read byte count, which marks the
maximum value for a device, since some drivers try to set MMRBC to the
highest allowed value and rely on such a function.

Based on patch set by Stephen Hemminger <shemminger@linux-foundation.org>

Cc: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Peter Oruba <peter.oruba@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Peter Oruba and committed by
Greg Kroah-Hartman
d556ad4b e4585da2

+182 -1
+160
drivers/pci/pci.c
··· 1375 1375 #endif 1376 1376 1377 1377 /** 1378 + * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count 1379 + * @dev: PCI device to query 1380 + * 1381 + * Returns mmrbc: maximum designed memory read count in bytes 1382 + * or appropriate error value. 1383 + */ 1384 + int pcix_get_max_mmrbc(struct pci_dev *dev) 1385 + { 1386 + int ret, err, cap; 1387 + u32 stat; 1388 + 1389 + cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 1390 + if (!cap) 1391 + return -EINVAL; 1392 + 1393 + err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); 1394 + if (err) 1395 + return -EINVAL; 1396 + 1397 + ret = (stat & PCI_X_STATUS_MAX_READ) >> 12; 1398 + 1399 + return ret; 1400 + } 1401 + EXPORT_SYMBOL(pcix_get_max_mmrbc); 1402 + 1403 + /** 1404 + * pcix_get_mmrbc - get PCI-X maximum memory read byte count 1405 + * @dev: PCI device to query 1406 + * 1407 + * Returns mmrbc: maximum memory read count in bytes 1408 + * or appropriate error value. 1409 + */ 1410 + int pcix_get_mmrbc(struct pci_dev *dev) 1411 + { 1412 + int ret, cap; 1413 + u32 cmd; 1414 + 1415 + cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 1416 + if (!cap) 1417 + return -EINVAL; 1418 + 1419 + ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); 1420 + if (!ret) 1421 + ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); 1422 + 1423 + return ret; 1424 + } 1425 + EXPORT_SYMBOL(pcix_get_mmrbc); 1426 + 1427 + /** 1428 + * pcix_set_mmrbc - set PCI-X maximum memory read byte count 1429 + * @dev: PCI device to query 1430 + * @mmrbc: maximum memory read count in bytes 1431 + * valid values are 512, 1024, 2048, 4096 1432 + * 1433 + * If possible sets maximum memory read byte count, some bridges have erratas 1434 + * that prevent this. 1435 + */ 1436 + int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) 1437 + { 1438 + int cap, err = -EINVAL; 1439 + u32 stat, cmd, v, o; 1440 + 1441 + if (mmrbc < 512 || mmrbc > 4096 || (mmrbc & (mmrbc-1))) 1442 + goto out; 1443 + 1444 + v = ffs(mmrbc) - 10; 1445 + 1446 + cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 1447 + if (!cap) 1448 + goto out; 1449 + 1450 + err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); 1451 + if (err) 1452 + goto out; 1453 + 1454 + if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) 1455 + return -E2BIG; 1456 + 1457 + err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); 1458 + if (err) 1459 + goto out; 1460 + 1461 + o = (cmd & PCI_X_CMD_MAX_READ) >> 2; 1462 + if (o != v) { 1463 + if (v > o && dev->bus && 1464 + (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC)) 1465 + return -EIO; 1466 + 1467 + cmd &= ~PCI_X_CMD_MAX_READ; 1468 + cmd |= v << 2; 1469 + err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); 1470 + } 1471 + out: 1472 + return err; 1473 + } 1474 + EXPORT_SYMBOL(pcix_set_mmrbc); 1475 + 1476 + /** 1477 + * pcie_get_readrq - get PCI Express read request size 1478 + * @dev: PCI device to query 1479 + * 1480 + * Returns maximum memory read request in bytes 1481 + * or appropriate error value. 1482 + */ 1483 + int pcie_get_readrq(struct pci_dev *dev) 1484 + { 1485 + int ret, cap; 1486 + u16 ctl; 1487 + 1488 + cap = pci_find_capability(dev, PCI_CAP_ID_EXP); 1489 + if (!cap) 1490 + return -EINVAL; 1491 + 1492 + ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); 1493 + if (!ret) 1494 + ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12); 1495 + 1496 + return ret; 1497 + } 1498 + EXPORT_SYMBOL(pcie_get_readrq); 1499 + 1500 + /** 1501 + * pcie_set_readrq - set PCI Express maximum memory read request 1502 + * @dev: PCI device to query 1503 + * @count: maximum memory read count in bytes 1504 + * valid values are 128, 256, 512, 1024, 2048, 4096 1505 + * 1506 + * If possible sets maximum read byte count 1507 + */ 1508 + int pcie_set_readrq(struct pci_dev *dev, int rq) 1509 + { 1510 + int cap, err = -EINVAL; 1511 + u16 ctl, v; 1512 + 1513 + if (rq < 128 || rq > 4096 || (rq & (rq-1))) 1514 + goto out; 1515 + 1516 + v = (ffs(rq) - 8) << 12; 1517 + 1518 + cap = pci_find_capability(dev, PCI_CAP_ID_EXP); 1519 + if (!cap) 1520 + goto out; 1521 + 1522 + err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); 1523 + if (err) 1524 + goto out; 1525 + 1526 + if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) { 1527 + ctl &= ~PCI_EXP_DEVCTL_READRQ; 1528 + ctl |= v; 1529 + err = pci_write_config_dword(dev, cap + PCI_EXP_DEVCTL, ctl); 1530 + } 1531 + 1532 + out: 1533 + return err; 1534 + } 1535 + EXPORT_SYMBOL(pcie_set_readrq); 1536 + 1537 + /** 1378 1538 * pci_select_bars - Make BAR mask from the type of resource 1379 1539 * @dev: the PCI device for which BAR mask is made 1380 1540 * @flags: resource type mask to be selected
+16
drivers/pci/quirks.c
··· 627 627 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); 628 628 #endif /* CONFIG_X86_IO_APIC */ 629 629 630 + /* 631 + * Some settings of MMRBC can lead to data corruption so block changes. 632 + * See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide 633 + */ 634 + static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev) 635 + { 636 + unsigned char revid; 637 + 638 + pci_read_config_byte(dev, PCI_REVISION_ID, &revid); 639 + if (dev->subordinate && revid <= 0x12) { 640 + printk(KERN_INFO "AMD8131 rev %x detected, disabling PCI-X MMRBC\n", 641 + revid); 642 + dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC; 643 + } 644 + } 645 + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_mmrbc); 630 646 631 647 /* 632 648 * FIXME: it is questionable that quirk_via_acpi
+6 -1
include/linux/pci.h
··· 111 111 112 112 typedef unsigned short __bitwise pci_bus_flags_t; 113 113 enum pci_bus_flags { 114 - PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, 114 + PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, 115 + PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2, 115 116 }; 116 117 117 118 struct pci_cap_saved_state { ··· 550 549 void pci_msi_off(struct pci_dev *dev); 551 550 int pci_set_dma_mask(struct pci_dev *dev, u64 mask); 552 551 int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); 552 + int pcix_get_max_mmrbc(struct pci_dev *dev); 553 + int pcix_get_mmrbc(struct pci_dev *dev); 554 + int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); 555 + int pcie_set_readrq(struct pci_dev *dev, int rq); 553 556 void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); 554 557 int __must_check pci_assign_resource(struct pci_dev *dev, int i); 555 558 int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);