rio.c (2ec3ba69faf301fb599e3651515e808e8efa533e) rio.c (9edbc30b434f56258d03faac5daf37a555384db3)
1/*
2 * RapidIO interconnect services
3 * (RapidIO Interconnect Specification, http://www.rapidio.org)
4 *
5 * Copyright 2005 MontaVista Software, Inc.
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * Copyright 2009 Integrated Device Technology, Inc.

--- 20 unchanged lines hidden (view full) ---

29#include <linux/interrupt.h>
30
31#include "rio.h"
32
33static LIST_HEAD(rio_devices);
34static DEFINE_SPINLOCK(rio_global_list_lock);
35
36static LIST_HEAD(rio_mports);
1/*
2 * RapidIO interconnect services
3 * (RapidIO Interconnect Specification, http://www.rapidio.org)
4 *
5 * Copyright 2005 MontaVista Software, Inc.
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * Copyright 2009 Integrated Device Technology, Inc.

--- 20 unchanged lines hidden (view full) ---

29#include <linux/interrupt.h>
30
31#include "rio.h"
32
33static LIST_HEAD(rio_devices);
34static DEFINE_SPINLOCK(rio_global_list_lock);
35
36static LIST_HEAD(rio_mports);
37static LIST_HEAD(rio_scans);
37static DEFINE_MUTEX(rio_mport_list_lock);
38static unsigned char next_portid;
39static DEFINE_SPINLOCK(rio_mmap_lock);
40
41/**
42 * rio_local_get_device_id - Get the base/extended device id for a port
43 * @port: RIO master port from which to get the deviceid
44 *

--- 1552 unchanged lines hidden (view full) ---

1597
1598 return port;
1599}
1600
1601/**
1602 * rio_register_scan - enumeration/discovery method registration interface
1603 * @mport_id: mport device ID for which fabric scan routine has to be set
1604 * (RIO_MPORT_ANY = set for all available mports)
38static DEFINE_MUTEX(rio_mport_list_lock);
39static unsigned char next_portid;
40static DEFINE_SPINLOCK(rio_mmap_lock);
41
42/**
43 * rio_local_get_device_id - Get the base/extended device id for a port
44 * @port: RIO master port from which to get the deviceid
45 *

--- 1552 unchanged lines hidden (view full) ---

1598
1599 return port;
1600}
1601
1602/**
1603 * rio_register_scan - enumeration/discovery method registration interface
1604 * @mport_id: mport device ID for which fabric scan routine has to be set
1605 * (RIO_MPORT_ANY = set for all available mports)
1605 * @scan_ops: enumeration/discovery control structure
1606 * @scan_ops: enumeration/discovery operations structure
1606 *
1607 *
1607 * Assigns enumeration or discovery method to the specified mport device (or all
1608 * available mports if RIO_MPORT_ANY is specified).
1608 * Registers enumeration/discovery operations with RapidIO subsystem and
1609 * attaches it to the specified mport device (or all available mports
1610 * if RIO_MPORT_ANY is specified).
1611 *
1609 * Returns error if the mport already has an enumerator attached to it.
1612 * Returns error if the mport already has an enumerator attached to it.
1610 * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns
1611 * an error if was unable to find at least one available mport.
1613 * In case of RIO_MPORT_ANY skips mports with valid scan routines (no error).
1612 */
1613int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
1614{
1615 struct rio_mport *port;
1614 */
1615int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
1616{
1617 struct rio_mport *port;
1616 int rc = -EBUSY;
1618 struct rio_scan_node *scan;
1619 int rc = 0;
1617
1620
1618 mutex_lock(&rio_mport_list_lock);
1619 list_for_each_entry(port, &rio_mports, node) {
1620 if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
1621 if (port->nscan && mport_id == RIO_MPORT_ANY)
1622 continue;
1623 else if (port->nscan)
1624 break;
1621 pr_debug("RIO: %s for mport_id=%d\n", __func__, mport_id);
1625
1622
1626 port->nscan = scan_ops;
1627 rc = 0;
1623 if ((mport_id != RIO_MPORT_ANY && mport_id >= RIO_MAX_MPORTS) ||
1624 !scan_ops)
1625 return -EINVAL;
1628
1626
1629 if (mport_id != RIO_MPORT_ANY)
1630 break;
1627 mutex_lock(&rio_mport_list_lock);
1628
1629 /*
1630 * Check if there is another enumerator already registered for
1631 * the same mport ID (including RIO_MPORT_ANY). Multiple enumerators
1632 * for the same mport ID are not supported.
1633 */
1634 list_for_each_entry(scan, &rio_scans, node) {
1635 if (scan->mport_id == mport_id) {
1636 rc = -EBUSY;
1637 goto err_out;
1631 }
1632 }
1638 }
1639 }
1640
1641 /*
1642 * Allocate and initialize new scan registration node.
1643 */
1644 scan = kzalloc(sizeof(*scan), GFP_KERNEL);
1645 if (!scan) {
1646 rc = -ENOMEM;
1647 goto err_out;
1648 }
1649
1650 scan->mport_id = mport_id;
1651 scan->ops = scan_ops;
1652
1653 /*
1654 * Traverse the list of registered mports to attach this new scan.
1655 *
1656 * The new scan with matching mport ID overrides any previously attached
1657 * scan assuming that old scan (if any) is the default one (based on the
1658 * enumerator registration check above).
1659 * If the new scan is the global one, it will be attached only to mports
1660 * that do not have their own individual operations already attached.
1661 */
1662 list_for_each_entry(port, &rio_mports, node) {
1663 if (port->id == mport_id) {
1664 port->nscan = scan_ops;
1665 break;
1666 } else if (mport_id == RIO_MPORT_ANY && !port->nscan)
1667 port->nscan = scan_ops;
1668 }
1669
1670 list_add_tail(&scan->node, &rio_scans);
1671
1672err_out:
1633 mutex_unlock(&rio_mport_list_lock);
1634
1635 return rc;
1636}
1637EXPORT_SYMBOL_GPL(rio_register_scan);
1638
1639/**
1640 * rio_unregister_scan - removes enumeration/discovery method from mport
1641 * @mport_id: mport device ID for which fabric scan routine has to be
1673 mutex_unlock(&rio_mport_list_lock);
1674
1675 return rc;
1676}
1677EXPORT_SYMBOL_GPL(rio_register_scan);
1678
1679/**
1680 * rio_unregister_scan - removes enumeration/discovery method from mport
1681 * @mport_id: mport device ID for which fabric scan routine has to be
1642 * unregistered (RIO_MPORT_ANY = set for all available mports)
1682 * unregistered (RIO_MPORT_ANY = apply to all mports that use
1683 * the specified scan_ops)
1684 * @scan_ops: enumeration/discovery operations structure
1643 *
1644 * Removes enumeration or discovery method assigned to the specified mport
1685 *
1686 * Removes enumeration or discovery method assigned to the specified mport
1645 * device (or all available mports if RIO_MPORT_ANY is specified).
1687 * device. If RIO_MPORT_ANY is specified, removes the specified operations from
1688 * all mports that have them attached.
1646 */
1689 */
1647int rio_unregister_scan(int mport_id)
1690int rio_unregister_scan(int mport_id, struct rio_scan *scan_ops)
1648{
1649 struct rio_mport *port;
1691{
1692 struct rio_mport *port;
1693 struct rio_scan_node *scan;
1650
1694
1695 pr_debug("RIO: %s for mport_id=%d\n", __func__, mport_id);
1696
1697 if (mport_id != RIO_MPORT_ANY && mport_id >= RIO_MAX_MPORTS)
1698 return -EINVAL;
1699
1651 mutex_lock(&rio_mport_list_lock);
1700 mutex_lock(&rio_mport_list_lock);
1652 list_for_each_entry(port, &rio_mports, node) {
1653 if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
1654 if (port->nscan)
1655 port->nscan = NULL;
1656 if (mport_id != RIO_MPORT_ANY)
1657 break;
1701
1702 list_for_each_entry(port, &rio_mports, node)
1703 if (port->id == mport_id ||
1704 (mport_id == RIO_MPORT_ANY && port->nscan == scan_ops))
1705 port->nscan = NULL;
1706
1707 list_for_each_entry(scan, &rio_scans, node)
1708 if (scan->mport_id == mport_id) {
1709 list_del(&scan->node);
1710 kfree(scan);
1658 }
1711 }
1659 }
1712
1660 mutex_unlock(&rio_mport_list_lock);
1661
1662 return 0;
1663}
1664EXPORT_SYMBOL_GPL(rio_unregister_scan);
1665
1713 mutex_unlock(&rio_mport_list_lock);
1714
1715 return 0;
1716}
1717EXPORT_SYMBOL_GPL(rio_unregister_scan);
1718
1719/**
1720 * rio_mport_scan - execute enumeration/discovery on the specified mport
1721 * @mport_id: number (ID) of mport device
1722 */
1723int rio_mport_scan(int mport_id)
1724{
1725 struct rio_mport *port = NULL;
1726 int rc;
1727
1728 mutex_lock(&rio_mport_list_lock);
1729 list_for_each_entry(port, &rio_mports, node) {
1730 if (port->id == mport_id)
1731 goto found;
1732 }
1733 mutex_unlock(&rio_mport_list_lock);
1734 return -ENODEV;
1735found:
1736 if (!port->nscan) {
1737 mutex_unlock(&rio_mport_list_lock);
1738 return -EINVAL;
1739 }
1740
1741 if (!try_module_get(port->nscan->owner)) {
1742 mutex_unlock(&rio_mport_list_lock);
1743 return -ENODEV;
1744 }
1745
1746 mutex_unlock(&rio_mport_list_lock);
1747
1748 if (port->host_deviceid >= 0)
1749 rc = port->nscan->enumerate(port, 0);
1750 else
1751 rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT);
1752
1753 module_put(port->nscan->owner);
1754 return rc;
1755}
1756
1666static void rio_fixup_device(struct rio_dev *dev)
1667{
1668}
1669
1670static int rio_init(void)
1671{
1672 struct rio_dev *dev = NULL;
1673

--- 12 unchanged lines hidden (view full) ---

1686
1687static void disc_work_handler(struct work_struct *_work)
1688{
1689 struct rio_disc_work *work;
1690
1691 work = container_of(_work, struct rio_disc_work, work);
1692 pr_debug("RIO: discovery work for mport %d %s\n",
1693 work->mport->id, work->mport->name);
1757static void rio_fixup_device(struct rio_dev *dev)
1758{
1759}
1760
1761static int rio_init(void)
1762{
1763 struct rio_dev *dev = NULL;
1764

--- 12 unchanged lines hidden (view full) ---

1777
1778static void disc_work_handler(struct work_struct *_work)
1779{
1780 struct rio_disc_work *work;
1781
1782 work = container_of(_work, struct rio_disc_work, work);
1783 pr_debug("RIO: discovery work for mport %d %s\n",
1784 work->mport->id, work->mport->name);
1694 work->mport->nscan->discover(work->mport, 0);
1785 if (try_module_get(work->mport->nscan->owner)) {
1786 work->mport->nscan->discover(work->mport, 0);
1787 module_put(work->mport->nscan->owner);
1788 }
1695}
1696
1697int rio_init_mports(void)
1698{
1699 struct rio_mport *port;
1700 struct rio_disc_work *work;
1701 int n = 0;
1702
1703 if (!next_portid)
1704 return -ENODEV;
1705
1706 /*
1707 * First, run enumerations and check if we need to perform discovery
1708 * on any of the registered mports.
1709 */
1710 mutex_lock(&rio_mport_list_lock);
1711 list_for_each_entry(port, &rio_mports, node) {
1712 if (port->host_deviceid >= 0) {
1789}
1790
1791int rio_init_mports(void)
1792{
1793 struct rio_mport *port;
1794 struct rio_disc_work *work;
1795 int n = 0;
1796
1797 if (!next_portid)
1798 return -ENODEV;
1799
1800 /*
1801 * First, run enumerations and check if we need to perform discovery
1802 * on any of the registered mports.
1803 */
1804 mutex_lock(&rio_mport_list_lock);
1805 list_for_each_entry(port, &rio_mports, node) {
1806 if (port->host_deviceid >= 0) {
1713 if (port->nscan)
1807 if (port->nscan && try_module_get(port->nscan->owner)) {
1714 port->nscan->enumerate(port, 0);
1808 port->nscan->enumerate(port, 0);
1809 module_put(port->nscan->owner);
1810 }
1715 } else
1716 n++;
1717 }
1718 mutex_unlock(&rio_mport_list_lock);
1719
1720 if (!n)
1721 goto no_disc;
1722
1723 /*
1724 * If we have mports that require discovery schedule a discovery work
1725 * for each of them. If the code below fails to allocate needed
1726 * resources, exit without error to keep results of enumeration
1727 * process (if any).
1811 } else
1812 n++;
1813 }
1814 mutex_unlock(&rio_mport_list_lock);
1815
1816 if (!n)
1817 goto no_disc;
1818
1819 /*
1820 * If we have mports that require discovery schedule a discovery work
1821 * for each of them. If the code below fails to allocate needed
1822 * resources, exit without error to keep results of enumeration
1823 * process (if any).
1728 * TODO: Implement restart of dicovery process for all or
1824 * TODO: Implement restart of discovery process for all or
1729 * individual discovering mports.
1730 */
1731 rio_wq = alloc_workqueue("riodisc", 0, 0);
1732 if (!rio_wq) {
1733 pr_err("RIO: unable allocate rio_wq\n");
1734 goto no_disc;
1735 }
1736

--- 9 unchanged lines hidden (view full) ---

1746 list_for_each_entry(port, &rio_mports, node) {
1747 if (port->host_deviceid < 0 && port->nscan) {
1748 work[n].mport = port;
1749 INIT_WORK(&work[n].work, disc_work_handler);
1750 queue_work(rio_wq, &work[n].work);
1751 n++;
1752 }
1753 }
1825 * individual discovering mports.
1826 */
1827 rio_wq = alloc_workqueue("riodisc", 0, 0);
1828 if (!rio_wq) {
1829 pr_err("RIO: unable allocate rio_wq\n");
1830 goto no_disc;
1831 }
1832

--- 9 unchanged lines hidden (view full) ---

1842 list_for_each_entry(port, &rio_mports, node) {
1843 if (port->host_deviceid < 0 && port->nscan) {
1844 work[n].mport = port;
1845 INIT_WORK(&work[n].work, disc_work_handler);
1846 queue_work(rio_wq, &work[n].work);
1847 n++;
1848 }
1849 }
1754 mutex_unlock(&rio_mport_list_lock);
1755
1756 flush_workqueue(rio_wq);
1850
1851 flush_workqueue(rio_wq);
1852 mutex_unlock(&rio_mport_list_lock);
1757 pr_debug("RIO: destroy discovery workqueue\n");
1758 destroy_workqueue(rio_wq);
1759 kfree(work);
1760
1761no_disc:
1762 rio_init();
1763
1764 return 0;

--- 14 unchanged lines hidden (view full) ---

1779 (void)get_options(str, ARRAY_SIZE(hdids), hdids);
1780 return 1;
1781}
1782
1783__setup("riohdid=", rio_hdid_setup);
1784
1785int rio_register_mport(struct rio_mport *port)
1786{
1853 pr_debug("RIO: destroy discovery workqueue\n");
1854 destroy_workqueue(rio_wq);
1855 kfree(work);
1856
1857no_disc:
1858 rio_init();
1859
1860 return 0;

--- 14 unchanged lines hidden (view full) ---

1875 (void)get_options(str, ARRAY_SIZE(hdids), hdids);
1876 return 1;
1877}
1878
1879__setup("riohdid=", rio_hdid_setup);
1880
1881int rio_register_mport(struct rio_mport *port)
1882{
1883 struct rio_scan_node *scan = NULL;
1884
1787 if (next_portid >= RIO_MAX_MPORTS) {
1788 pr_err("RIO: reached specified max number of mports\n");
1789 return 1;
1790 }
1791
1792 port->id = next_portid++;
1793 port->host_deviceid = rio_get_hdid(port->id);
1794 port->nscan = NULL;
1885 if (next_portid >= RIO_MAX_MPORTS) {
1886 pr_err("RIO: reached specified max number of mports\n");
1887 return 1;
1888 }
1889
1890 port->id = next_portid++;
1891 port->host_deviceid = rio_get_hdid(port->id);
1892 port->nscan = NULL;
1893
1795 mutex_lock(&rio_mport_list_lock);
1796 list_add_tail(&port->node, &rio_mports);
1894 mutex_lock(&rio_mport_list_lock);
1895 list_add_tail(&port->node, &rio_mports);
1896
1897 /*
1898 * Check if there are any registered enumeration/discovery operations
1899 * that have to be attached to the added mport.
1900 */
1901 list_for_each_entry(scan, &rio_scans, node) {
1902 if (port->id == scan->mport_id ||
1903 scan->mport_id == RIO_MPORT_ANY) {
1904 port->nscan = scan->ops;
1905 if (port->id == scan->mport_id)
1906 break;
1907 }
1908 }
1797 mutex_unlock(&rio_mport_list_lock);
1909 mutex_unlock(&rio_mport_list_lock);
1910
1911 pr_debug("RIO: %s %s id=%d\n", __func__, port->name, port->id);
1798 return 0;
1799}
1800
1801EXPORT_SYMBOL_GPL(rio_local_get_device_id);
1802EXPORT_SYMBOL_GPL(rio_get_device);
1803EXPORT_SYMBOL_GPL(rio_get_asm);
1804EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
1805EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
1806EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
1807EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
1808EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
1809EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
1810EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
1811EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
1812EXPORT_SYMBOL_GPL(rio_init_mports);
1912 return 0;
1913}
1914
1915EXPORT_SYMBOL_GPL(rio_local_get_device_id);
1916EXPORT_SYMBOL_GPL(rio_get_device);
1917EXPORT_SYMBOL_GPL(rio_get_asm);
1918EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
1919EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
1920EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
1921EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
1922EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
1923EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
1924EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
1925EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
1926EXPORT_SYMBOL_GPL(rio_init_mports);