Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1211bb6d authored by Thomas Klein's avatar Thomas Klein Committed by Jeff Garzik
Browse files

ehea: fix for dlpar support



Certain resources may only be allocated when first logical port is available,
and must be removed when last logical port has been removed.

Signed-off-by: default avatarThomas Klein <tklein@de.ibm.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent d1dea38d
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -39,7 +39,7 @@
#include <asm/io.h>
#include <asm/io.h>


#define DRV_NAME	"ehea"
#define DRV_NAME	"ehea"
#define DRV_VERSION	"EHEA_0057"
#define DRV_VERSION	"EHEA_0058"


#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
+45 −22
Original line number Original line Diff line number Diff line
@@ -2133,6 +2133,28 @@ static int ehea_clean_all_portres(struct ehea_port *port)
	return ret;
	return ret;
}
}


static void ehea_remove_adapter_mr (struct ehea_adapter *adapter)
{
	int i;

	for (i=0; i < EHEA_MAX_PORTS; i++)
		if (adapter->port[i])
			return;

	ehea_rem_mr(&adapter->mr);
}

static int ehea_add_adapter_mr (struct ehea_adapter *adapter)
{
	int i;

	for (i=0; i < EHEA_MAX_PORTS; i++)
		if (adapter->port[i])
			return 0;

	return ehea_reg_kernel_mr(adapter, &adapter->mr);
}

static int ehea_up(struct net_device *dev)
static int ehea_up(struct net_device *dev)
{
{
	int ret, i;
	int ret, i;
@@ -2583,7 +2605,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
	struct device_node *eth_dn = NULL;
	struct device_node *eth_dn = NULL;


	u32 *dn_log_port_id;
	u32 *dn_log_port_id;
	int port_setup_ok = 0;
	int i = 0;
	int i = 0;


	lhea_dn = adapter->ebus_dev->ofdev.node;
	lhea_dn = adapter->ebus_dev->ofdev.node;
@@ -2597,6 +2618,12 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
			continue;
			continue;
		}
		}


		if (ehea_add_adapter_mr(adapter)) {
			ehea_error("creating MR failed");
			of_node_put(eth_dn);
			return -EIO;
		}

		adapter->port[i] = ehea_setup_single_port(adapter,
		adapter->port[i] = ehea_setup_single_port(adapter,
							  *dn_log_port_id,
							  *dn_log_port_id,
							  eth_dn);
							  eth_dn);
@@ -2604,18 +2631,13 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
			ehea_info("%s -> logical port id #%d",
			ehea_info("%s -> logical port id #%d",
				  adapter->port[i]->netdev->name,
				  adapter->port[i]->netdev->name,
				  *dn_log_port_id);
				  *dn_log_port_id);
		else
			ehea_remove_adapter_mr(adapter);

		i++;
		i++;
	};
	};


	/* Check for succesfully set up ports */
	return 0;
	for (i = 0; i < EHEA_MAX_PORTS; i++)
		if (adapter->port[i])
			port_setup_ok++;

	if (port_setup_ok)
		return 0;	/* At least some ports are setup correctly */

	return -EINVAL;
}
}


static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
@@ -2667,6 +2689,11 @@ static ssize_t ehea_probe_port(struct device *dev,
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (ehea_add_adapter_mr(adapter)) {
		ehea_error("creating MR failed");
		return -EIO;
	}

	port = ehea_setup_single_port(adapter, logical_port_id, eth_dn);
	port = ehea_setup_single_port(adapter, logical_port_id, eth_dn);


	of_node_put(eth_dn);
	of_node_put(eth_dn);
@@ -2680,8 +2707,10 @@ static ssize_t ehea_probe_port(struct device *dev,


		ehea_info("added %s (logical port id=%d)", port->netdev->name,
		ehea_info("added %s (logical port id=%d)", port->netdev->name,
			  logical_port_id);
			  logical_port_id);
	} else
	} else {
		ehea_remove_adapter_mr(adapter);
		return -EIO;
		return -EIO;
	}


	return (ssize_t) count;
	return (ssize_t) count;
}
}
@@ -2716,6 +2745,8 @@ static ssize_t ehea_remove_port(struct device *dev,
		return -EINVAL;
		return -EINVAL;
	}
	}


	ehea_remove_adapter_mr(adapter);

	return (ssize_t) count;
	return (ssize_t) count;
}
}


@@ -2776,18 +2807,13 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,


	dev->ofdev.dev.driver_data = adapter;
	dev->ofdev.dev.driver_data = adapter;


	ret = ehea_reg_kernel_mr(adapter, &adapter->mr);
	if (ret) {
		dev_err(&dev->ofdev.dev, "reg_mr_adapter failed\n");
		goto out_free_ad;
	}


	/* initialize adapter and ports */
	/* initialize adapter and ports */
	/* get adapter properties */
	/* get adapter properties */
	ret = ehea_sense_adapter_attr(adapter);
	ret = ehea_sense_adapter_attr(adapter);
	if (ret) {
	if (ret) {
		dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret);
		dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret);
		goto out_free_res;
		goto out_free_ad;
	}
	}


	adapter->neq = ehea_create_eq(adapter,
	adapter->neq = ehea_create_eq(adapter,
@@ -2795,7 +2821,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
	if (!adapter->neq) {
	if (!adapter->neq) {
		ret = -EIO;
		ret = -EIO;
		dev_err(&dev->ofdev.dev, "NEQ creation failed");
		dev_err(&dev->ofdev.dev, "NEQ creation failed");
		goto out_free_res;
		goto out_free_ad;
	}
	}


	tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
	tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
@@ -2840,9 +2866,6 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
out_kill_eq:
out_kill_eq:
	ehea_destroy_eq(adapter->neq);
	ehea_destroy_eq(adapter->neq);


out_free_res:
	ehea_rem_mr(&adapter->mr);

out_free_ad:
out_free_ad:
	kfree(adapter);
	kfree(adapter);
out:
out:
@@ -2868,7 +2891,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev)
	tasklet_kill(&adapter->neq_tasklet);
	tasklet_kill(&adapter->neq_tasklet);


	ehea_destroy_eq(adapter->neq);
	ehea_destroy_eq(adapter->neq);
	ehea_rem_mr(&adapter->mr);
	ehea_remove_adapter_mr(adapter);
	kfree(adapter);
	kfree(adapter);
	return 0;
	return 0;
}
}