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

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
...@@ -39,7 +39,7 @@ ...@@ -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)
......
...@@ -2133,6 +2133,28 @@ static int ehea_clean_all_portres(struct ehea_port *port) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment