aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ehea
diff options
context:
space:
mode:
authorJan-Bernd Themann <ossthema@de.ibm.com>2007-02-28 12:34:02 -0500
committerJeff Garzik <jeff@garzik.org>2007-04-28 11:00:56 -0400
commit1acf2318dd136edfbfa30f1f33b43f69f2e2ec6c (patch)
tree2d79a977fc773f43e6f8be76f5fdaf0b8c251226 /drivers/net/ehea
parent459e536b1ddfd217ec8a3437a3214968a98223c7 (diff)
ehea: dynamic add / remove port
This patch introduces functionality to dynamically add / remove ehea ports via an userspace DLPAR tool. It creates a subnode for each logical port in the sysfs. Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/ehea')
-rw-r--r--drivers/net/ehea/ehea.h9
-rw-r--r--drivers/net/ehea/ehea_main.c439
2 files changed, 323 insertions, 125 deletions
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 42295d61ecd8..e595d6b38e7c 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
39#include <asm/io.h> 39#include <asm/io.h>
40 40
41#define DRV_NAME "ehea" 41#define DRV_NAME "ehea"
42#define DRV_VERSION "EHEA_0046" 42#define DRV_VERSION "EHEA_0048"
43 43
44#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ 44#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
45 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) 45 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -380,10 +380,11 @@ struct ehea_port_res {
380}; 380};
381 381
382 382
383#define EHEA_MAX_PORTS 16
383struct ehea_adapter { 384struct ehea_adapter {
384 u64 handle; 385 u64 handle;
385 u8 num_ports; 386 struct ibmebus_dev *ebus_dev;
386 struct ehea_port *port[16]; 387 struct ehea_port *port[EHEA_MAX_PORTS];
387 struct ehea_eq *neq; /* notification event queue */ 388 struct ehea_eq *neq; /* notification event queue */
388 struct workqueue_struct *ehea_wq; 389 struct workqueue_struct *ehea_wq;
389 struct tasklet_struct neq_tasklet; 390 struct tasklet_struct neq_tasklet;
@@ -406,7 +407,7 @@ struct ehea_port {
406 struct net_device *netdev; 407 struct net_device *netdev;
407 struct net_device_stats stats; 408 struct net_device_stats stats;
408 struct ehea_port_res port_res[EHEA_MAX_PORT_RES]; 409 struct ehea_port_res port_res[EHEA_MAX_PORT_RES];
409 struct device_node *of_dev_node; /* Open Firmware Device Node */ 410 struct of_device ofdev; /* Open Firmware Device */
410 struct ehea_mc_list *mc_list; /* Multicast MAC addresses */ 411 struct ehea_mc_list *mc_list; /* Multicast MAC addresses */
411 struct vlan_group *vgrp; 412 struct vlan_group *vgrp;
412 struct ehea_eq *qp_eq; 413 struct ehea_eq *qp_eq;
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 58364a0ff378..3527b391214d 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -580,7 +580,7 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter,
580{ 580{
581 int i; 581 int i;
582 582
583 for (i = 0; i < adapter->num_ports; i++) 583 for (i = 0; i < EHEA_MAX_PORTS; i++)
584 if (adapter->port[i]) 584 if (adapter->port[i])
585 if (adapter->port[i]->logical_port_id == logical_port) 585 if (adapter->port[i]->logical_port_id == logical_port)
586 return adapter->port[i]; 586 return adapter->port[i];
@@ -2276,8 +2276,6 @@ static void ehea_tx_watchdog(struct net_device *dev)
2276int ehea_sense_adapter_attr(struct ehea_adapter *adapter) 2276int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
2277{ 2277{
2278 struct hcp_query_ehea *cb; 2278 struct hcp_query_ehea *cb;
2279 struct device_node *lhea_dn = NULL;
2280 struct device_node *eth_dn = NULL;
2281 u64 hret; 2279 u64 hret;
2282 int ret; 2280 int ret;
2283 2281
@@ -2294,18 +2292,6 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
2294 goto out_herr; 2292 goto out_herr;
2295 } 2293 }
2296 2294
2297 /* Determine the number of available logical ports
2298 * by counting the child nodes of the lhea OFDT entry
2299 */
2300 adapter->num_ports = 0;
2301 lhea_dn = of_find_node_by_name(lhea_dn, "lhea");
2302 do {
2303 eth_dn = of_get_next_child(lhea_dn, eth_dn);
2304 if (eth_dn)
2305 adapter->num_ports++;
2306 } while ( eth_dn );
2307 of_node_put(lhea_dn);
2308
2309 adapter->max_mc_mac = cb->max_mc_mac - 1; 2295 adapter->max_mc_mac = cb->max_mc_mac - 1;
2310 ret = 0; 2296 ret = 0;
2311 2297
@@ -2315,79 +2301,150 @@ out:
2315 return ret; 2301 return ret;
2316} 2302}
2317 2303
2318static int ehea_setup_single_port(struct ehea_port *port, 2304int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo)
2319 struct device_node *dn)
2320{ 2305{
2321 int ret;
2322 u64 hret;
2323 struct net_device *dev = port->netdev;
2324 struct ehea_adapter *adapter = port->adapter;
2325 struct hcp_ehea_port_cb4 *cb4; 2306 struct hcp_ehea_port_cb4 *cb4;
2326 u32 *dn_log_port_id; 2307 u64 hret;
2327 int jumbo = 0; 2308 int ret = 0;
2328
2329 sema_init(&port->port_lock, 1);
2330 port->state = EHEA_PORT_DOWN;
2331 port->sig_comp_iv = sq_entries / 10;
2332
2333 if (!dn) {
2334 ehea_error("bad device node: dn=%p", dn);
2335 ret = -EINVAL;
2336 goto out;
2337 }
2338
2339 port->of_dev_node = dn;
2340
2341 /* Determine logical port id */
2342 dn_log_port_id = (u32*)get_property(dn, "ibm,hea-port-no", NULL);
2343
2344 if (!dn_log_port_id) {
2345 ehea_error("bad device node: dn_log_port_id=%p",
2346 dn_log_port_id);
2347 ret = -EINVAL;
2348 goto out;
2349 }
2350 port->logical_port_id = *dn_log_port_id;
2351
2352 port->mc_list = kzalloc(sizeof(struct ehea_mc_list), GFP_KERNEL);
2353 if (!port->mc_list) {
2354 ret = -ENOMEM;
2355 goto out;
2356 }
2357
2358 INIT_LIST_HEAD(&port->mc_list->list);
2359 2309
2360 ret = ehea_sense_port_attr(port); 2310 *jumbo = 0;
2361 if (ret)
2362 goto out;
2363 2311
2364 /* Enable Jumbo frames */ 2312 /* (Try to) enable *jumbo frames */
2365 cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL); 2313 cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
2366 if (!cb4) { 2314 if (!cb4) {
2367 ehea_error("no mem for cb4"); 2315 ehea_error("no mem for cb4");
2316 ret = -ENOMEM;
2317 goto out;
2368 } else { 2318 } else {
2369 hret = ehea_h_query_ehea_port(adapter->handle, 2319 hret = ehea_h_query_ehea_port(port->adapter->handle,
2370 port->logical_port_id, 2320 port->logical_port_id,
2371 H_PORT_CB4, 2321 H_PORT_CB4,
2372 H_PORT_CB4_JUMBO, cb4); 2322 H_PORT_CB4_JUMBO, cb4);
2373
2374 if (hret == H_SUCCESS) { 2323 if (hret == H_SUCCESS) {
2375 if (cb4->jumbo_frame) 2324 if (cb4->jumbo_frame)
2376 jumbo = 1; 2325 *jumbo = 1;
2377 else { 2326 else {
2378 cb4->jumbo_frame = 1; 2327 cb4->jumbo_frame = 1;
2379 hret = ehea_h_modify_ehea_port(adapter->handle, 2328 hret = ehea_h_modify_ehea_port(port->adapter->
2329 handle,
2380 port-> 2330 port->
2381 logical_port_id, 2331 logical_port_id,
2382 H_PORT_CB4, 2332 H_PORT_CB4,
2383 H_PORT_CB4_JUMBO, 2333 H_PORT_CB4_JUMBO,
2384 cb4); 2334 cb4);
2385 if (hret == H_SUCCESS) 2335 if (hret == H_SUCCESS)
2386 jumbo = 1; 2336 *jumbo = 1;
2387 } 2337 }
2388 } 2338 } else
2339 ret = -EINVAL;
2340
2389 kfree(cb4); 2341 kfree(cb4);
2390 } 2342 }
2343out:
2344 return ret;
2345}
2346
2347static ssize_t ehea_show_port_id(struct device *dev,
2348 struct device_attribute *attr, char *buf)
2349{
2350 struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
2351 return sprintf(buf, "0x%X", port->logical_port_id);
2352}
2353
2354static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id,
2355 NULL);
2356
2357static void __devinit logical_port_release(struct device *dev)
2358{
2359 struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
2360 of_node_put(port->ofdev.node);
2361}
2362
2363static struct device *ehea_register_port(struct ehea_port *port,
2364 struct device_node *dn)
2365{
2366 int ret;
2367
2368 port->ofdev.node = of_node_get(dn);
2369 port->ofdev.dev.parent = &port->adapter->ebus_dev->ofdev.dev;
2370
2371 sprintf(port->ofdev.dev.bus_id, "port%d", port->logical_port_id);
2372 port->ofdev.dev.release = logical_port_release;
2373
2374 ret = of_device_register(&port->ofdev);
2375 if (ret) {
2376 ehea_error("failed to register device. ret=%d", ret);
2377 goto out;
2378 }
2379
2380 ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id);
2381 if (ret) {
2382 ehea_error("failed to register attributes, ret=%d", ret);
2383 goto out_unreg_of_dev;
2384 }
2385
2386 return &port->ofdev.dev;
2387
2388out_unreg_of_dev:
2389 of_device_unregister(&port->ofdev);
2390out:
2391 return NULL;
2392}
2393
2394static void ehea_unregister_port(struct ehea_port *port)
2395{
2396 device_remove_file(&port->ofdev.dev, &dev_attr_log_port_id);
2397 of_device_unregister(&port->ofdev);
2398}
2399
2400struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
2401 u32 logical_port_id,
2402 struct device_node *dn)
2403{
2404 int ret;
2405 struct net_device *dev;
2406 struct ehea_port *port;
2407 struct device *port_dev;
2408 int jumbo;
2409
2410 /* allocate memory for the port structures */
2411 dev = alloc_etherdev(sizeof(struct ehea_port));
2412
2413 if (!dev) {
2414 ehea_error("no mem for net_device");
2415 ret = -ENOMEM;
2416 goto out_err;
2417 }
2418
2419 port = netdev_priv(dev);
2420
2421 sema_init(&port->port_lock, 1);
2422 port->state = EHEA_PORT_DOWN;
2423 port->sig_comp_iv = sq_entries / 10;
2424
2425 port->adapter = adapter;
2426 port->netdev = dev;
2427 port->logical_port_id = logical_port_id;
2428
2429 port->msg_enable = netif_msg_init(msg_level, EHEA_MSG_DEFAULT);
2430
2431 port->mc_list = kzalloc(sizeof(struct ehea_mc_list), GFP_KERNEL);
2432 if (!port->mc_list) {
2433 ret = -ENOMEM;
2434 goto out_free_ethdev;
2435 }
2436
2437 INIT_LIST_HEAD(&port->mc_list->list);
2438
2439 ret = ehea_sense_port_attr(port);
2440 if (ret)
2441 goto out_free_mc_list;
2442
2443 port_dev = ehea_register_port(port, dn);
2444 if (!port_dev)
2445 goto out_free_mc_list;
2446
2447 SET_NETDEV_DEV(dev, port_dev);
2391 2448
2392 /* initialize net_device structure */ 2449 /* initialize net_device structure */
2393 SET_MODULE_OWNER(dev); 2450 SET_MODULE_OWNER(dev);
@@ -2420,79 +2477,216 @@ static int ehea_setup_single_port(struct ehea_port *port,
2420 ret = register_netdev(dev); 2477 ret = register_netdev(dev);
2421 if (ret) { 2478 if (ret) {
2422 ehea_error("register_netdev failed. ret=%d", ret); 2479 ehea_error("register_netdev failed. ret=%d", ret);
2423 goto out_free; 2480 goto out_unreg_port;
2424 } 2481 }
2425 2482
2483 ret = ehea_get_jumboframe_status(port, &jumbo);
2484 if (ret)
2485 ehea_error("failed determining jumbo frame status for %s",
2486 port->netdev->name);
2487
2426 ehea_info("%s: Jumbo frames are %sabled", dev->name, 2488 ehea_info("%s: Jumbo frames are %sabled", dev->name,
2427 jumbo == 1 ? "en" : "dis"); 2489 jumbo == 1 ? "en" : "dis");
2428 2490
2429 port->netdev = dev; 2491 return port;
2430 ret = 0;
2431 goto out;
2432 2492
2433out_free: 2493out_unreg_port:
2494 ehea_unregister_port(port);
2495
2496out_free_mc_list:
2434 kfree(port->mc_list); 2497 kfree(port->mc_list);
2435out: 2498
2436 return ret; 2499out_free_ethdev:
2500 free_netdev(dev);
2501
2502out_err:
2503 ehea_error("setting up logical port with id=%d failed, ret=%d",
2504 logical_port_id, ret);
2505 return NULL;
2506}
2507
2508static void ehea_shutdown_single_port(struct ehea_port *port)
2509{
2510 unregister_netdev(port->netdev);
2511 ehea_unregister_port(port);
2512 kfree(port->mc_list);
2513 free_netdev(port->netdev);
2437} 2514}
2438 2515
2439static int ehea_setup_ports(struct ehea_adapter *adapter) 2516static int ehea_setup_ports(struct ehea_adapter *adapter)
2440{ 2517{
2441 int ret; 2518 struct device_node *lhea_dn;
2519 struct device_node *eth_dn = NULL;
2520
2521 u32 *dn_log_port_id;
2442 int port_setup_ok = 0; 2522 int port_setup_ok = 0;
2443 struct ehea_port *port; 2523 int i = 0;
2444 struct device_node *dn = NULL; 2524
2445 struct net_device *dev; 2525 lhea_dn = adapter->ebus_dev->ofdev.node;
2446 int i; 2526 do {
2527 eth_dn = of_get_next_child(lhea_dn, eth_dn);
2528 if (!eth_dn)
2529 break;
2447 2530
2448 /* get port properties for all ports */ 2531 dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
2449 for (i = 0; i < adapter->num_ports; i++) { 2532 NULL);
2533 if (!dn_log_port_id) {
2534 ehea_error("bad device node: eth_dn name=%s",
2535 eth_dn->full_name);
2536 continue;
2537 }
2450 2538
2539 adapter->port[i] = ehea_setup_single_port(adapter,
2540 *dn_log_port_id,
2541 eth_dn);
2451 if (adapter->port[i]) 2542 if (adapter->port[i])
2452 continue; /* port already up and running */ 2543 ehea_info("%s -> logical port id #%d",
2544 adapter->port[i]->netdev->name,
2545 *dn_log_port_id);
2546 i++;
2547 } while (eth_dn);
2548
2549 of_node_put(lhea_dn);
2453 2550
2454 /* allocate memory for the port structures */ 2551 /* Check for succesfully set up ports */
2455 dev = alloc_etherdev(sizeof(struct ehea_port)); 2552 for (i = 0; i < EHEA_MAX_PORTS; i++)
2553 if (adapter->port[i])
2554 port_setup_ok++;
2456 2555
2457 if (!dev) { 2556 if (port_setup_ok)
2458 ehea_error("no mem for net_device"); 2557 return 0; /* At least some ports are setup correctly */
2558
2559 return -EINVAL;
2560}
2561
2562static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
2563 u32 logical_port_id)
2564{
2565 struct device_node *lhea_dn;
2566 struct device_node *eth_dn = NULL;
2567 u32 *dn_log_port_id;
2568
2569 lhea_dn = adapter->ebus_dev->ofdev.node;
2570 do {
2571 eth_dn = of_get_next_child(lhea_dn, eth_dn);
2572 if (!eth_dn)
2459 break; 2573 break;
2460 }
2461 2574
2462 port = netdev_priv(dev); 2575 dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
2463 port->adapter = adapter; 2576 NULL);
2464 port->netdev = dev;
2465 adapter->port[i] = port;
2466 port->msg_enable = netif_msg_init(msg_level, EHEA_MSG_DEFAULT);
2467 2577
2468 dn = of_find_node_by_name(dn, "ethernet"); 2578 if (dn_log_port_id)
2469 ret = ehea_setup_single_port(port, dn); 2579 if (*dn_log_port_id == logical_port_id)
2470 if (ret) { 2580 return eth_dn;
2471 /* Free mem for this port struct. The others will be 2581
2472 processed on rollback */ 2582 } while (eth_dn);
2473 free_netdev(dev); 2583
2474 adapter->port[i] = NULL; 2584 of_node_put(lhea_dn);
2475 ehea_error("eHEA port %d setup failed, ret=%d", i, ret); 2585
2476 } 2586 return NULL;
2587}
2588
2589static ssize_t ehea_probe_port(struct device *dev,
2590 struct device_attribute *attr,
2591 const char *buf, size_t count)
2592{
2593 struct ehea_adapter *adapter = dev->driver_data;
2594 struct ehea_port *port;
2595 struct device_node *eth_dn = NULL;
2596 int i;
2597
2598 u32 logical_port_id;
2599
2600 sscanf(buf, "%X", &logical_port_id);
2601
2602 port = ehea_get_port(adapter, logical_port_id);
2603
2604 if (port) {
2605 ehea_info("adding port with logical port id=%d failed. port "
2606 "already configured as %s.", logical_port_id,
2607 port->netdev->name);
2608 return -EINVAL;
2477 } 2609 }
2610
2611 eth_dn = ehea_get_eth_dn(adapter, logical_port_id);
2478 2612
2479 of_node_put(dn); 2613 if (!eth_dn) {
2614 ehea_info("no logical port with id %d found", logical_port_id);
2615 return -EINVAL;
2616 }
2617
2618 port = ehea_setup_single_port(adapter, logical_port_id, eth_dn);
2480 2619
2481 /* Check for succesfully set up ports */ 2620 if (port) {
2482 for (i = 0; i < adapter->num_ports; i++) 2621 for (i=0; i < EHEA_MAX_PORTS; i++)
2483 if (adapter->port[i]) 2622 if (!adapter->port[i]) {
2484 port_setup_ok++; 2623 adapter->port[i] = port;
2624 break;
2625 }
2485 2626
2486 if (port_setup_ok) 2627 ehea_info("added %s (logical port id=%d)", port->netdev->name,
2487 ret = 0; /* At least some ports are setup correctly */ 2628 logical_port_id);
2488 else 2629 } else
2489 ret = -EINVAL; 2630 return -EIO;
2490 2631
2632 return (ssize_t) count;
2633}
2634
2635static ssize_t ehea_remove_port(struct device *dev,
2636 struct device_attribute *attr,
2637 const char *buf, size_t count)
2638{
2639 struct ehea_adapter *adapter = dev->driver_data;
2640 struct ehea_port *port;
2641 int i;
2642 u32 logical_port_id;
2643
2644 sscanf(buf, "%X", &logical_port_id);
2645
2646 port = ehea_get_port(adapter, logical_port_id);
2647
2648 if (port) {
2649 ehea_info("removed %s (logical port id=%d)", port->netdev->name,
2650 logical_port_id);
2651
2652 ehea_shutdown_single_port(port);
2653
2654 for (i=0; i < EHEA_MAX_PORTS; i++)
2655 if (adapter->port[i] == port) {
2656 adapter->port[i] = NULL;
2657 break;
2658 }
2659 } else {
2660 ehea_error("removing port with logical port id=%d failed. port "
2661 "not configured.", logical_port_id);
2662 return -EINVAL;
2663 }
2664
2665 return (ssize_t) count;
2666}
2667
2668static DEVICE_ATTR(probe_port, S_IWUSR, NULL, ehea_probe_port);
2669static DEVICE_ATTR(remove_port, S_IWUSR, NULL, ehea_remove_port);
2670
2671int ehea_create_device_sysfs(struct ibmebus_dev *dev)
2672{
2673 int ret = device_create_file(&dev->ofdev.dev, &dev_attr_probe_port);
2674 if (ret)
2675 goto out;
2676
2677 ret = device_create_file(&dev->ofdev.dev, &dev_attr_remove_port);
2678out:
2491 return ret; 2679 return ret;
2492} 2680}
2493 2681
2494static int __devinit ehea_probe(struct ibmebus_dev *dev, 2682void ehea_remove_device_sysfs(struct ibmebus_dev *dev)
2495 const struct of_device_id *id) 2683{
2684 device_remove_file(&dev->ofdev.dev, &dev_attr_probe_port);
2685 device_remove_file(&dev->ofdev.dev, &dev_attr_remove_port);
2686}
2687
2688static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
2689 const struct of_device_id *id)
2496{ 2690{
2497 struct ehea_adapter *adapter; 2691 struct ehea_adapter *adapter;
2498 u64 *adapter_handle; 2692 u64 *adapter_handle;
@@ -2505,6 +2699,8 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev,
2505 goto out; 2699 goto out;
2506 } 2700 }
2507 2701
2702 adapter->ebus_dev = dev;
2703
2508 adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle", 2704 adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle",
2509 NULL); 2705 NULL);
2510 if (adapter_handle) 2706 if (adapter_handle)
@@ -2534,7 +2730,6 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev,
2534 dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret); 2730 dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret);
2535 goto out_free_res; 2731 goto out_free_res;
2536 } 2732 }
2537 dev_info(&dev->ofdev.dev, "%d eHEA ports found\n", adapter->num_ports);
2538 2733
2539 adapter->neq = ehea_create_eq(adapter, 2734 adapter->neq = ehea_create_eq(adapter,
2540 EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); 2735 EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1);
@@ -2558,15 +2753,21 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev,
2558 if (!adapter->ehea_wq) 2753 if (!adapter->ehea_wq)
2559 goto out_free_irq; 2754 goto out_free_irq;
2560 2755
2756 if (ehea_create_device_sysfs(dev))
2757 goto out_kill_wq;
2758
2561 ret = ehea_setup_ports(adapter); 2759 ret = ehea_setup_ports(adapter);
2562 if (ret) { 2760 if (ret) {
2563 dev_err(&dev->ofdev.dev, "setup_ports failed"); 2761 dev_err(&dev->ofdev.dev, "setup_ports failed");
2564 goto out_kill_wq; 2762 goto out_rem_dev_sysfs;
2565 } 2763 }
2566 2764
2567 ret = 0; 2765 ret = 0;
2568 goto out; 2766 goto out;
2569 2767
2768out_rem_dev_sysfs:
2769 ehea_remove_device_sysfs(dev);
2770
2570out_kill_wq: 2771out_kill_wq:
2571 destroy_workqueue(adapter->ehea_wq); 2772 destroy_workqueue(adapter->ehea_wq);
2572 2773
@@ -2585,24 +2786,20 @@ out:
2585 return ret; 2786 return ret;
2586} 2787}
2587 2788
2588static void ehea_shutdown_single_port(struct ehea_port *port)
2589{
2590 unregister_netdev(port->netdev);
2591 kfree(port->mc_list);
2592 free_netdev(port->netdev);
2593}
2594
2595static int __devexit ehea_remove(struct ibmebus_dev *dev) 2789static int __devexit ehea_remove(struct ibmebus_dev *dev)
2596{ 2790{
2597 struct ehea_adapter *adapter = dev->ofdev.dev.driver_data; 2791 struct ehea_adapter *adapter = dev->ofdev.dev.driver_data;
2598 u64 hret; 2792 u64 hret;
2599 int i; 2793 int i;
2600 2794
2601 for (i = 0; i < adapter->num_ports; i++) 2795 for (i = 0; i < EHEA_MAX_PORTS; i++)
2602 if (adapter->port[i]) { 2796 if (adapter->port[i]) {
2603 ehea_shutdown_single_port(adapter->port[i]); 2797 ehea_shutdown_single_port(adapter->port[i]);
2604 adapter->port[i] = NULL; 2798 adapter->port[i] = NULL;
2605 } 2799 }
2800
2801 ehea_remove_device_sysfs(dev);
2802
2606 destroy_workqueue(adapter->ehea_wq); 2803 destroy_workqueue(adapter->ehea_wq);
2607 2804
2608 ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); 2805 ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter);
@@ -2658,7 +2855,7 @@ static struct of_device_id ehea_device_table[] = {
2658static struct ibmebus_driver ehea_driver = { 2855static struct ibmebus_driver ehea_driver = {
2659 .name = "ehea", 2856 .name = "ehea",
2660 .id_table = ehea_device_table, 2857 .id_table = ehea_device_table,
2661 .probe = ehea_probe, 2858 .probe = ehea_probe_adapter,
2662 .remove = ehea_remove, 2859 .remove = ehea_remove,
2663}; 2860};
2664 2861