diff options
author | Thomas Klein <osstklei@de.ibm.com> | 2007-04-26 05:56:43 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-04-28 11:01:06 -0400 |
commit | 1211bb6dcd935c48e864d4eecbf8a684e982419a (patch) | |
tree | 83b79afed772ecde9399513deb9cf4ab14831411 /drivers/net/ehea/ehea_main.c | |
parent | d1dea38d54311f6b3dd37ce485e794bd133e3593 (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.c | 67 |
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 | ||
2136 | static 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 | |||
2147 | static 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 | |||
2136 | static int ehea_up(struct net_device *dev) | 2158 | static 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 | ||
2621 | static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, | 2643 | 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 | 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: | |||
2840 | out_kill_eq: | 2866 | out_kill_eq: |
2841 | ehea_destroy_eq(adapter->neq); | 2867 | ehea_destroy_eq(adapter->neq); |
2842 | 2868 | ||
2843 | out_free_res: | ||
2844 | ehea_rem_mr(&adapter->mr); | ||
2845 | |||
2846 | out_free_ad: | 2869 | out_free_ad: |
2847 | kfree(adapter); | 2870 | kfree(adapter); |
2848 | out: | 2871 | out: |
@@ -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 | } |