aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_cm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_cm.c')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c34
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
1451static ssize_t set_mode(struct device *d, struct device_attribute *attr, 1451int 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
1482static 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
1487static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode); 1501static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
1488 1502
1489int ipoib_cm_add_mode_attr(struct net_device *dev) 1503int ipoib_cm_add_mode_attr(struct net_device *dev)