aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMark Debbage <mark.debbage@qlogic.com>2007-06-18 17:24:45 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-09 23:12:26 -0400
commit0df6291c8af2778d05f278d5738eef2c8fafa2dd (patch)
tree07eb25e1da424197dc89b0ace53d7c366b271cfa /drivers
parentd781b129f1e8b3e2f369d8035a61a5233832e65c (diff)
IB/ipath: Correct checking of swminor version field when using subports
When subports are required to run a program, this patch checks that the driver and the userspace library have compatible subport implementations. This is achieved through checks on the swminor version field built into the driver and userspace library. Bad combinations are reported through syslog and result in an error when opening the port. Signed-off-by: Mark Debbage <mark.debbage@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c64
1 files changed, 55 insertions, 9 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 931802b55cc5..fc83f40a933f 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -1403,6 +1403,38 @@ bail:
1403 return pollflag; 1403 return pollflag;
1404} 1404}
1405 1405
1406static int ipath_supports_subports(int user_swmajor, int user_swminor)
1407{
1408 /* no subport implementation prior to software version 1.3 */
1409 return (user_swmajor > 1) || (user_swminor >= 3);
1410}
1411
1412static int ipath_compatible_subports(int user_swmajor, int user_swminor)
1413{
1414 /* this code is written long-hand for clarity */
1415 if (IPATH_USER_SWMAJOR != user_swmajor) {
1416 /* no promise of compatibility if major mismatch */
1417 return 0;
1418 }
1419 if (IPATH_USER_SWMAJOR == 1) {
1420 switch (IPATH_USER_SWMINOR) {
1421 case 0:
1422 case 1:
1423 case 2:
1424 /* no subport implementation so cannot be compatible */
1425 return 0;
1426 case 3:
1427 /* 3 is only compatible with itself */
1428 return user_swminor == 3;
1429 default:
1430 /* >= 4 are compatible (or are expected to be) */
1431 return user_swminor >= 4;
1432 }
1433 }
1434 /* make no promises yet for future major versions */
1435 return 0;
1436}
1437
1406static int init_subports(struct ipath_devdata *dd, 1438static int init_subports(struct ipath_devdata *dd,
1407 struct ipath_portdata *pd, 1439 struct ipath_portdata *pd,
1408 const struct ipath_user_info *uinfo) 1440 const struct ipath_user_info *uinfo)
@@ -1418,14 +1450,26 @@ static int init_subports(struct ipath_devdata *dd,
1418 if (uinfo->spu_subport_cnt <= 1) 1450 if (uinfo->spu_subport_cnt <= 1)
1419 goto bail; 1451 goto bail;
1420 1452
1421 /* Old user binaries don't know about new subport implementation */ 1453 /* Self-consistency check for ipath_compatible_subports() */
1422 if ((uinfo->spu_userversion & 0xffff) != IPATH_USER_SWMINOR) { 1454 if (ipath_supports_subports(IPATH_USER_SWMAJOR, IPATH_USER_SWMINOR) &&
1455 !ipath_compatible_subports(IPATH_USER_SWMAJOR,
1456 IPATH_USER_SWMINOR)) {
1423 dev_info(&dd->pcidev->dev, 1457 dev_info(&dd->pcidev->dev,
1424 "Mismatched user minor version (%d) and driver " 1458 "Inconsistent ipath_compatible_subports()\n");
1425 "minor version (%d) while port sharing. Ensure " 1459 goto bail;
1460 }
1461
1462 /* Check for subport compatibility */
1463 if (!ipath_compatible_subports(uinfo->spu_userversion >> 16,
1464 uinfo->spu_userversion & 0xffff)) {
1465 dev_info(&dd->pcidev->dev,
1466 "Mismatched user version (%d.%d) and driver "
1467 "version (%d.%d) while port sharing. Ensure "
1426 "that driver and library are from the same " 1468 "that driver and library are from the same "
1427 "release.\n", 1469 "release.\n",
1470 (int) (uinfo->spu_userversion >> 16),
1428 (int) (uinfo->spu_userversion & 0xffff), 1471 (int) (uinfo->spu_userversion & 0xffff),
1472 IPATH_USER_SWMAJOR,
1429 IPATH_USER_SWMINOR); 1473 IPATH_USER_SWMINOR);
1430 goto bail; 1474 goto bail;
1431 } 1475 }
@@ -1729,14 +1773,13 @@ static int ipath_open(struct inode *in, struct file *fp)
1729 return fp->private_data ? 0 : -ENOMEM; 1773 return fp->private_data ? 0 : -ENOMEM;
1730} 1774}
1731 1775
1732
1733/* Get port early, so can set affinity prior to memory allocation */ 1776/* Get port early, so can set affinity prior to memory allocation */
1734static int ipath_assign_port(struct file *fp, 1777static int ipath_assign_port(struct file *fp,
1735 const struct ipath_user_info *uinfo) 1778 const struct ipath_user_info *uinfo)
1736{ 1779{
1737 int ret; 1780 int ret;
1738 int i_minor; 1781 int i_minor;
1739 unsigned swminor; 1782 unsigned swmajor, swminor;
1740 1783
1741 /* Check to be sure we haven't already initialized this file */ 1784 /* Check to be sure we haven't already initialized this file */
1742 if (port_fp(fp)) { 1785 if (port_fp(fp)) {
@@ -1745,7 +1788,8 @@ static int ipath_assign_port(struct file *fp,
1745 } 1788 }
1746 1789
1747 /* for now, if major version is different, bail */ 1790 /* for now, if major version is different, bail */
1748 if ((uinfo->spu_userversion >> 16) != IPATH_USER_SWMAJOR) { 1791 swmajor = uinfo->spu_userversion >> 16;
1792 if (swmajor != IPATH_USER_SWMAJOR) {
1749 ipath_dbg("User major version %d not same as driver " 1793 ipath_dbg("User major version %d not same as driver "
1750 "major %d\n", uinfo->spu_userversion >> 16, 1794 "major %d\n", uinfo->spu_userversion >> 16,
1751 IPATH_USER_SWMAJOR); 1795 IPATH_USER_SWMAJOR);
@@ -1760,7 +1804,8 @@ static int ipath_assign_port(struct file *fp,
1760 1804
1761 mutex_lock(&ipath_mutex); 1805 mutex_lock(&ipath_mutex);
1762 1806
1763 if (swminor == IPATH_USER_SWMINOR && uinfo->spu_subport_cnt && 1807 if (ipath_compatible_subports(swmajor, swminor) &&
1808 uinfo->spu_subport_cnt &&
1764 (ret = find_shared_port(fp, uinfo))) { 1809 (ret = find_shared_port(fp, uinfo))) {
1765 mutex_unlock(&ipath_mutex); 1810 mutex_unlock(&ipath_mutex);
1766 if (ret > 0) 1811 if (ret > 0)
@@ -2024,7 +2069,8 @@ static int ipath_port_info(struct ipath_portdata *pd, u16 subport,
2024 info.port = pd->port_port; 2069 info.port = pd->port_port;
2025 info.subport = subport; 2070 info.subport = subport;
2026 /* Don't return new fields if old library opened the port. */ 2071 /* Don't return new fields if old library opened the port. */
2027 if ((pd->userversion & 0xffff) == IPATH_USER_SWMINOR) { 2072 if (ipath_supports_subports(pd->userversion >> 16,
2073 pd->userversion & 0xffff)) {
2028 /* Number of user ports available for this device. */ 2074 /* Number of user ports available for this device. */
2029 info.num_ports = pd->port_dd->ipath_cfgports - 1; 2075 info.num_ports = pd->port_dd->ipath_cfgports - 1;
2030 info.num_subports = pd->port_subport_cnt; 2076 info.num_subports = pd->port_subport_cnt;