diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_cm.c')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_cm.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 24683fda8e21..175581cf478c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -1448,15 +1448,10 @@ static ssize_t show_mode(struct device *d, struct device_attribute *attr, | |||
1448 | return sprintf(buf, "datagram\n"); | 1448 | return sprintf(buf, "datagram\n"); |
1449 | } | 1449 | } |
1450 | 1450 | ||
1451 | static ssize_t set_mode(struct device *d, struct device_attribute *attr, | 1451 | int ipoib_set_mode(struct net_device *dev, const char *buf) |
1452 | const char *buf, size_t count) | ||
1453 | { | 1452 | { |
1454 | struct net_device *dev = to_net_dev(d); | ||
1455 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 1453 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
1456 | 1454 | ||
1457 | if (!rtnl_trylock()) | ||
1458 | return restart_syscall(); | ||
1459 | |||
1460 | /* flush paths if we switch modes so that connections are restarted */ | 1455 | /* flush paths if we switch modes so that connections are restarted */ |
1461 | if (IPOIB_CM_SUPPORTED(dev->dev_addr) && !strcmp(buf, "connected\n")) { | 1456 | if (IPOIB_CM_SUPPORTED(dev->dev_addr) && !strcmp(buf, "connected\n")) { |
1462 | set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); | 1457 | set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); |
@@ -1467,7 +1462,8 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr, | |||
1467 | priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; | 1462 | priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM; |
1468 | 1463 | ||
1469 | ipoib_flush_paths(dev); | 1464 | ipoib_flush_paths(dev); |
1470 | return count; | 1465 | rtnl_lock(); |
1466 | return 0; | ||
1471 | } | 1467 | } |
1472 | 1468 | ||
1473 | if (!strcmp(buf, "datagram\n")) { | 1469 | if (!strcmp(buf, "datagram\n")) { |
@@ -1476,14 +1472,32 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr, | |||
1476 | dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu)); | 1472 | dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu)); |
1477 | rtnl_unlock(); | 1473 | rtnl_unlock(); |
1478 | ipoib_flush_paths(dev); | 1474 | ipoib_flush_paths(dev); |
1479 | 1475 | rtnl_lock(); | |
1480 | return count; | 1476 | return 0; |
1481 | } | 1477 | } |
1482 | rtnl_unlock(); | ||
1483 | 1478 | ||
1484 | return -EINVAL; | 1479 | return -EINVAL; |
1485 | } | 1480 | } |
1486 | 1481 | ||
1482 | static ssize_t set_mode(struct device *d, struct device_attribute *attr, | ||
1483 | const char *buf, size_t count) | ||
1484 | { | ||
1485 | struct net_device *dev = to_net_dev(d); | ||
1486 | int ret; | ||
1487 | |||
1488 | if (!rtnl_trylock()) | ||
1489 | return restart_syscall(); | ||
1490 | |||
1491 | ret = ipoib_set_mode(dev, buf); | ||
1492 | |||
1493 | rtnl_unlock(); | ||
1494 | |||
1495 | if (!ret) | ||
1496 | return count; | ||
1497 | |||
1498 | return ret; | ||
1499 | } | ||
1500 | |||
1487 | static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode); | 1501 | static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode); |
1488 | 1502 | ||
1489 | int ipoib_cm_add_mode_attr(struct net_device *dev) | 1503 | int ipoib_cm_add_mode_attr(struct net_device *dev) |