===================================================================
@@ -423,6 +423,13 @@ static ssize_t set_port_type(struct devi
types[i] = mdev->caps.port_type[i+1];
}
+ if (priv->trig) {
+ if (++priv->changed_ports < mdev->caps.num_ports)
+ goto out;
+ else
+ priv->trig = priv->changed_ports = 0;
+ }
+
if (!(mdev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
for (i = 1; i <= mdev->caps.num_ports; i++) {
if (mdev->caps.possible_type[i] == MLX4_PORT_TYPE_AUTO) {
@@ -458,6 +465,23 @@ out:
return err ? err : count;
}
+static ssize_t trigger_port(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct mlx4_dev *mdev = pci_get_drvdata(pdev);
+ struct mlx4_priv *priv = container_of(mdev, struct mlx4_priv, dev);
+
+ if (!priv)
+ return -ENODEV;
+
+ mutex_lock(&priv->port_mutex);
+ priv->trig = 1;
+ mutex_unlock(&priv->port_mutex);
+ return count;
+}
+DEVICE_ATTR(port_trigger, S_IWUGO, NULL, trigger_port);
+
static int mlx4_load_fw(struct mlx4_dev *dev)
{
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -1110,6 +1134,13 @@ static void mlx4_cleanup_port_info(struc
device_remove_file(&info->dev->pdev->dev, &info->port_attr);
}
+static int mlx4_init_trigger(struct mlx4_priv *priv)
+{
+ memcpy(&priv->trigger_attr, &dev_attr_port_trigger,
+ sizeof(struct device_attribute));
+ return device_create_file(&priv->dev.pdev->dev, &priv->trigger_attr);
+}
+
static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct mlx4_priv *priv;
@@ -1241,6 +1272,10 @@ static int __mlx4_init_one(struct pci_de
if (err)
goto err_port;
+ err = mlx4_init_trigger(priv);
+ if (err)
+ goto err_register;
+
mlx4_sense_init(dev);
mlx4_start_sense(dev);
@@ -1248,6 +1283,8 @@ static int __mlx4_init_one(struct pci_de
return 0;
+err_register:
+ mlx4_unregister_device(dev);
err_port:
for (port = 1; port <= dev->caps.num_ports; port++)
mlx4_cleanup_port_info(&priv->port[port]);
@@ -1312,6 +1349,7 @@ static void mlx4_remove_one(struct pci_d
if (dev) {
mlx4_stop_sense(dev);
mlx4_unregister_device(dev);
+ device_remove_file(&dev->pdev->dev, &priv->trigger_attr);
for (p = 1; p <= dev->caps.num_ports; p++) {
mlx4_cleanup_port_info(&priv->port[p]);
===================================================================
@@ -317,6 +317,9 @@ struct mlx4_priv {
struct mlx4_uar driver_uar;
void __iomem *kar;
struct mlx4_port_info port[MLX4_MAX_PORTS + 1];
+ struct device_attribute trigger_attr;
+ int trig;
+ int changed_ports;
struct mlx4_sense sense;
struct mutex port_mutex;
};