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: Thomas Klein <tklein@de.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
Родитель
d1dea38d54
Коммит
1211bb6dcd
|
@ -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)
|
||||||
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 @@ out_free_irq:
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче