aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ehea/ehea_main.c
diff options
context:
space:
mode:
authorThomas Klein <osstklei@de.ibm.com>2007-04-26 05:56:43 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 11:01:06 -0400
commit1211bb6dcd935c48e864d4eecbf8a684e982419a (patch)
tree83b79afed772ecde9399513deb9cf4ab14831411 /drivers/net/ehea/ehea_main.c
parentd1dea38d54311f6b3dd37ce485e794bd133e3593 (diff)
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>
Diffstat (limited to 'drivers/net/ehea/ehea_main.c')
-rw-r--r--drivers/net/ehea/ehea_main.c67
1 files changed, 45 insertions, 22 deletions
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 368f8e3eb4a0..c7a5614e66c0 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2133,6 +2133,28 @@ static int ehea_clean_all_portres(struct ehea_port *port)
2133 return ret; 2133 return ret;
2134} 2134}
2135 2135
2136static void ehea_remove_adapter_mr (struct ehea_adapter *adapter)
2137{
2138 int i;
2139
2140 for (i=0; i < EHEA_MAX_PORTS; i++)
2141 if (adapter->port[i])
2142 return;
2143
2144 ehea_rem_mr(&adapter->mr);
2145}
2146
2147static int ehea_add_adapter_mr (struct ehea_adapter *adapter)
2148{
2149 int i;
2150
2151 for (i=0; i < EHEA_MAX_PORTS; i++)
2152 if (adapter->port[i])
2153 return 0;
2154
2155 return ehea_reg_kernel_mr(adapter, &adapter->mr);
2156}
2157
2136static int ehea_up(struct net_device *dev) 2158static int ehea_up(struct net_device *dev)
2137{ 2159{
2138 int ret, i; 2160 int ret, i;
@@ -2583,7 +2605,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
2583 struct device_node *eth_dn = NULL; 2605 struct device_node *eth_dn = NULL;
2584 2606
2585 u32 *dn_log_port_id; 2607 u32 *dn_log_port_id;
2586 int port_setup_ok = 0;
2587 int i = 0; 2608 int i = 0;
2588 2609
2589 lhea_dn = adapter->ebus_dev->ofdev.node; 2610 lhea_dn = adapter->ebus_dev->ofdev.node;
@@ -2597,6 +2618,12 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
2597 continue; 2618 continue;
2598 } 2619 }
2599 2620
2621 if (ehea_add_adapter_mr(adapter)) {
2622 ehea_error("creating MR failed");
2623 of_node_put(eth_dn);
2624 return -EIO;
2625 }
2626
2600 adapter->port[i] = ehea_setup_single_port(adapter, 2627 adapter->port[i] = ehea_setup_single_port(adapter,
2601 *dn_log_port_id, 2628 *dn_log_port_id,
2602 eth_dn); 2629 eth_dn);
@@ -2604,18 +2631,13 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
2604 ehea_info("%s -> logical port id #%d", 2631 ehea_info("%s -> logical port id #%d",
2605 adapter->port[i]->netdev->name, 2632 adapter->port[i]->netdev->name,
2606 *dn_log_port_id); 2633 *dn_log_port_id);
2634 else
2635 ehea_remove_adapter_mr(adapter);
2636
2607 i++; 2637 i++;
2608 }; 2638 };
2609 2639
2610 /* Check for succesfully set up ports */ 2640 return 0;
2611 for (i = 0; i < EHEA_MAX_PORTS; i++)
2612 if (adapter->port[i])
2613 port_setup_ok++;
2614
2615 if (port_setup_ok)
2616 return 0; /* At least some ports are setup correctly */
2617
2618 return -EINVAL;
2619} 2641}
2620 2642
2621static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, 2643static 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 return -EINVAL; 2689 return -EINVAL;
2668 } 2690 }
2669 2691
2692 if (ehea_add_adapter_mr(adapter)) {
2693 ehea_error("creating MR failed");
2694 return -EIO;
2695 }
2696
2670 port = ehea_setup_single_port(adapter, logical_port_id, eth_dn); 2697 port = ehea_setup_single_port(adapter, logical_port_id, eth_dn);
2671 2698
2672 of_node_put(eth_dn); 2699 of_node_put(eth_dn);
@@ -2680,8 +2707,10 @@ static ssize_t ehea_probe_port(struct device *dev,
2680 2707
2681 ehea_info("added %s (logical port id=%d)", port->netdev->name, 2708 ehea_info("added %s (logical port id=%d)", port->netdev->name,
2682 logical_port_id); 2709 logical_port_id);
2683 } else 2710 } else {
2711 ehea_remove_adapter_mr(adapter);
2684 return -EIO; 2712 return -EIO;
2713 }
2685 2714
2686 return (ssize_t) count; 2715 return (ssize_t) count;
2687} 2716}
@@ -2716,6 +2745,8 @@ static ssize_t ehea_remove_port(struct device *dev,
2716 return -EINVAL; 2745 return -EINVAL;
2717 } 2746 }
2718 2747
2748 ehea_remove_adapter_mr(adapter);
2749
2719 return (ssize_t) count; 2750 return (ssize_t) count;
2720} 2751}
2721 2752
@@ -2776,18 +2807,13 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
2776 2807
2777 dev->ofdev.dev.driver_data = adapter; 2808 dev->ofdev.dev.driver_data = adapter;
2778 2809
2779 ret = ehea_reg_kernel_mr(adapter, &adapter->mr);
2780 if (ret) {
2781 dev_err(&dev->ofdev.dev, "reg_mr_adapter failed\n");
2782 goto out_free_ad;
2783 }
2784 2810
2785 /* initialize adapter and ports */ 2811 /* initialize adapter and ports */
2786 /* get adapter properties */ 2812 /* get adapter properties */
2787 ret = ehea_sense_adapter_attr(adapter); 2813 ret = ehea_sense_adapter_attr(adapter);
2788 if (ret) { 2814 if (ret) {
2789 dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret); 2815 dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret);
2790 goto out_free_res; 2816 goto out_free_ad;
2791 } 2817 }
2792 2818
2793 adapter->neq = ehea_create_eq(adapter, 2819 adapter->neq = ehea_create_eq(adapter,
@@ -2795,7 +2821,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
2795 if (!adapter->neq) { 2821 if (!adapter->neq) {
2796 ret = -EIO; 2822 ret = -EIO;
2797 dev_err(&dev->ofdev.dev, "NEQ creation failed"); 2823 dev_err(&dev->ofdev.dev, "NEQ creation failed");
2798 goto out_free_res; 2824 goto out_free_ad;
2799 } 2825 }
2800 2826
2801 tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, 2827 tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
@@ -2840,9 +2866,6 @@ out_free_irq:
2840out_kill_eq: 2866out_kill_eq:
2841 ehea_destroy_eq(adapter->neq); 2867 ehea_destroy_eq(adapter->neq);
2842 2868
2843out_free_res:
2844 ehea_rem_mr(&adapter->mr);
2845
2846out_free_ad: 2869out_free_ad:
2847 kfree(adapter); 2870 kfree(adapter);
2848out: 2871out:
@@ -2868,7 +2891,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev)
2868 tasklet_kill(&adapter->neq_tasklet); 2891 tasklet_kill(&adapter->neq_tasklet);
2869 2892
2870 ehea_destroy_eq(adapter->neq); 2893 ehea_destroy_eq(adapter->neq);
2871 ehea_rem_mr(&adapter->mr); 2894 ehea_remove_adapter_mr(adapter);
2872 kfree(adapter); 2895 kfree(adapter);
2873 return 0; 2896 return 0;
2874} 2897}