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); |