From 00aaea2f95d73d4e2b5e45cf77c3cbb16c59e87f Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Mon, 9 Jun 2008 15:17:37 +0100 Subject: ehea: set mac address fix eHEA has to call firmware functions in order to change the mac address of a logical port. This patch checks if the logical port is up when calling the register / deregister mac address calls. If the port is down these firmware calls would fail and are therefore not executed. Signed-off-by: Jan-Bernd Themann Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/net/ehea/ehea_main.c') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 287a61918739..faae01dc1c4b 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -1766,16 +1766,20 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) mutex_lock(&ehea_bcmc_regs.lock); /* Deregister old MAC in pHYP */ - ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); - if (ret) - goto out_upregs; + if (port->state == EHEA_PORT_UP) { + ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); + if (ret) + goto out_upregs; + } port->mac_addr = cb0->port_mac_addr << 16; /* Register new MAC in pHYP */ - ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); - if (ret) - goto out_upregs; + if (port->state == EHEA_PORT_UP) { + ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); + if (ret) + goto out_upregs; + } ret = 0; -- cgit v1.2.3 From 4bb073c0e32a0862bdb5215d11af19f6c0180c98 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 12 Jun 2008 02:22:02 -0700 Subject: net: Eliminate flush_scheduled_work() calls while RTNL is held. If the RTNL is held when we invoke flush_scheduled_work() we could deadlock. One such case is linkwatch, it is a work struct which tries to grab the RTNL semaphore. The most common case are net driver ->stop() methods. The simplest conversion is to instead use cancel_{delayed_}work_sync() explicitly on the various work struct the driver uses. This is an OK transformation because these work structs are doing things like resetting the chip, restarting link negotiation, and so forth. And if we're bringing down the device, we're about to turn the chip off and reset it anways. So if we cancel a pending work event, that's fine here. Some drivers were working around this deadlock by using a msleep() polling loop of some sort, and those cases are converted to instead use cancel_{delayed_}work_sync() as well. Signed-off-by: David S. Miller --- drivers/net/ehea/ehea_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/ehea/ehea_main.c') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index faae01dc1c4b..075fd547421e 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2605,7 +2605,8 @@ static int ehea_stop(struct net_device *dev) if (netif_msg_ifdown(port)) ehea_info("disabling port %s", dev->name); - flush_scheduled_work(); + cancel_work_sync(&port->reset_task); + mutex_lock(&port->port_lock); netif_stop_queue(dev); port_napi_disable(port); -- cgit v1.2.3