Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] bonding: simplify code and get rid of warning
From: Jay Vosburgh @ 2008-02-20 16:57 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: bonding-devel, netdev
In-Reply-To: <20080218210426.022bbe36@extreme>

Stephen Hemminger <shemminger@vyatta.com> wrote:

>Get rid of warning and simplify code that looks up vlan tag.
>No need to get tag, then copy it. Also no need for a local status
>variable.

	Granted, the current code is suboptimal, but I don't see any
warnings compiling this (gcc 4.1.2).  What are you getting?

	-J

---
	-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com


>Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>---
>Patch against current 2.6.25 version.
>
>--- a/drivers/net/bonding/bond_alb.c	2008-02-18 20:58:53.000000000 -0800
>+++ b/drivers/net/bonding/bond_alb.c	2008-02-18 21:01:10.000000000 -0800
>@@ -678,12 +678,8 @@ static struct slave *rlb_choose_channel(
> 		}
>
> 		if (!list_empty(&bond->vlan_list)) {
>-			unsigned short vlan_id;
>-			int res = vlan_get_tag(skb, &vlan_id);
>-			if (!res) {
>+			if (!vlan_get_tag(skb, &client_info->vlan_id))
> 				client_info->tag = 1;
>-				client_info->vlan_id = vlan_id;
>-			}
> 		}
>
> 		if (!client_info->assigned) {
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [git patches] net driver fixes
From: Jeff Garzik @ 2008-02-20 16:55 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Note:  this is based off of Linus's latest commit
(5d9c4a7de64d398604a978d267a6987f1f4025b7), since all my previous
submissions are now upstream (thanks!).


Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

 MAINTAINERS                        |   11 +-
 drivers/net/cs89x0.c               |   12 +-
 drivers/net/ehea/ehea.h            |   34 +++++-
 drivers/net/ehea/ehea_main.c       |  281 +++++++++++++++++++++++++++++++++---
 drivers/net/fs_enet/fs_enet-main.c |    7 +-
 drivers/net/gianfar.c              |   14 +-
 drivers/net/igb/igb_main.c         |   15 +--
 drivers/net/pcmcia/pcnet_cs.c      |   10 +-
 drivers/net/phy/mdio_bus.c         |    4 +-
 drivers/net/sis190.c               |   15 ++-
 drivers/net/tlan.c                 |   64 ++++----
 drivers/net/tulip/uli526x.c        |   12 ++-
 drivers/net/virtio_net.c           |    2 +-
 drivers/s390/net/claw.c            |   39 +++---
 14 files changed, 399 insertions(+), 121 deletions(-)

Adrian Bunk (1):
      net/phy/mdio_bus.c: fix a check-after-use

Andy Gospodarek (1):
      igb: fix legacy mode irq issue

Becky Bruce (1):
      gianfar: don't pass NULL dev ptr to DMA ops

Bill Hayes (1):
      igb: Fix panic with NICs with 1000BASE-SX PHY

Christian Borntraeger (1):
      virtio_net: Fix oops on early interrupts - introduced by virtio reset code

Francois Romieu (1):
      sis190: read the mac address from the eeprom first

Grant Grundler (2):
      update TULIP MAINTAINERS
      uli526x partially recognizing interface

Harvey Harrison (1):
      tlan: add static to function definitions

Julia Lawall (1):
      claw: make use of DIV_ROUND_UP

Komuro (1):
      pcnet_cs: if AX88190-based card, printk "use axnet_cs instead" message.

Leonardo Potenza (1):
      drivers/net/cs89x0.c: compilation warning fix

Scott Wood (1):
      fs_enet: Don't call phy_mii_ioctl() in atomic context.

Thomas Klein (1):
      ehea: add kdump support

diff --git a/MAINTAINERS b/MAINTAINERS
index 082d1ee..53b6e60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3887,10 +3887,13 @@ M:	trivial@kernel.org
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-TULIP NETWORK DRIVER
-L:	tulip-users@lists.sourceforge.net
-W:	http://sourceforge.net/projects/tulip/
-S:	Orphan
+TULIP NETWORK DRIVERS
+P:	Grant Grundler
+M:	grundler@parisc-linux.org
+P:	Kyle McMartin
+M:	kyle@parisc-linux.org
+L:	netdev@vger.kernel.org
+S:	Maintained
 
 TUN/TAP driver
 P:	Maxim Krasnyansky
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 5717509..348371f 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -172,30 +172,30 @@ static char version[] __initdata =
    them to system IRQ numbers. This mapping is card specific and is set to
    the configuration of the Cirrus Eval board for this chip. */
 #ifdef CONFIG_ARCH_CLPS7500
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
    { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
 static unsigned int cs8900_irq_map[] = {12,0,0,0};
 #elif defined(CONFIG_SH_HICOSH4)
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
    { 0x0300, 0};
 static unsigned int cs8900_irq_map[] = {1,0,0,0};
 #elif defined(CONFIG_MACH_IXDP2351)
-static unsigned int netcard_portlist[] __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
 #include <asm/irq.h>
 #elif defined(CONFIG_ARCH_IXDP2X01)
 #include <asm/irq.h>
-static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
 #elif defined(CONFIG_ARCH_PNX010X)
 #include <asm/irq.h>
 #include <asm/arch/gpio.h>
 #define CIRRUS_DEFAULT_BASE	IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000)	/* = Physical address 0x48200000 */
 #define CIRRUS_DEFAULT_IRQ	VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
-static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
+static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
 #else
-static unsigned int netcard_portlist[] __initdata =
+static unsigned int netcard_portlist[] __used __initdata =
    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
 static unsigned int cs8900_irq_map[] = {10,11,12,5};
 #endif
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 88fb53e..7c4ead3 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0083"
+#define DRV_VERSION	"EHEA_0087"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
@@ -386,6 +386,13 @@ struct ehea_port_res {
 
 
 #define EHEA_MAX_PORTS 16
+
+#define EHEA_NUM_PORTRES_FW_HANDLES    6  /* QP handle, SendCQ handle,
+					     RecvCQ handle, EQ handle,
+					     SendMR handle, RecvMR handle */
+#define EHEA_NUM_PORT_FW_HANDLES       1  /* EQ handle */
+#define EHEA_NUM_ADAPTER_FW_HANDLES    2  /* MR handle, NEQ handle */
+
 struct ehea_adapter {
 	u64 handle;
 	struct of_device *ofdev;
@@ -405,6 +412,31 @@ struct ehea_mc_list {
 	u64 macaddr;
 };
 
+/* kdump support */
+struct ehea_fw_handle_entry {
+	u64 adh;               /* Adapter Handle */
+	u64 fwh;               /* Firmware Handle */
+};
+
+struct ehea_fw_handle_array {
+	struct ehea_fw_handle_entry *arr;
+	int num_entries;
+	struct semaphore lock;
+};
+
+struct ehea_bcmc_reg_entry {
+	u64 adh;               /* Adapter Handle */
+	u32 port_id;           /* Logical Port Id */
+	u8 reg_type;           /* Registration Type */
+	u64 macaddr;
+};
+
+struct ehea_bcmc_reg_array {
+	struct ehea_bcmc_reg_entry *arr;
+	int num_entries;
+	struct semaphore lock;
+};
+
 #define EHEA_PORT_UP 1
 #define EHEA_PORT_DOWN 0
 #define EHEA_PHY_LINK_UP 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c051c7e..21af674 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -35,6 +35,7 @@
 #include <linux/if_ether.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+#include <asm/kexec.h>
 
 #include <net/ip.h>
 
@@ -98,8 +99,10 @@ static int port_name_cnt;
 static LIST_HEAD(adapter_list);
 u64 ehea_driver_flags;
 struct work_struct ehea_rereg_mr_task;
-
 struct semaphore dlpar_mem_lock;
+struct ehea_fw_handle_array ehea_fw_handles;
+struct ehea_bcmc_reg_array ehea_bcmc_regs;
+
 
 static int __devinit ehea_probe_adapter(struct of_device *dev,
 					const struct of_device_id *id);
@@ -132,6 +135,160 @@ void ehea_dump(void *adr, int len, char *msg)
 	}
 }
 
+static void ehea_update_firmware_handles(void)
+{
+	struct ehea_fw_handle_entry *arr = NULL;
+	struct ehea_adapter *adapter;
+	int num_adapters = 0;
+	int num_ports = 0;
+	int num_portres = 0;
+	int i = 0;
+	int num_fw_handles, k, l;
+
+	/* Determine number of handles */
+	list_for_each_entry(adapter, &adapter_list, list) {
+		num_adapters++;
+
+		for (k = 0; k < EHEA_MAX_PORTS; k++) {
+			struct ehea_port *port = adapter->port[k];
+
+			if (!port || (port->state != EHEA_PORT_UP))
+				continue;
+
+			num_ports++;
+			num_portres += port->num_def_qps + port->num_add_tx_qps;
+		}
+	}
+
+	num_fw_handles = num_adapters * EHEA_NUM_ADAPTER_FW_HANDLES +
+			 num_ports * EHEA_NUM_PORT_FW_HANDLES +
+			 num_portres * EHEA_NUM_PORTRES_FW_HANDLES;
+
+	if (num_fw_handles) {
+		arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
+		if (!arr)
+			return;  /* Keep the existing array */
+	} else
+		goto out_update;
+
+	list_for_each_entry(adapter, &adapter_list, list) {
+		for (k = 0; k < EHEA_MAX_PORTS; k++) {
+			struct ehea_port *port = adapter->port[k];
+
+			if (!port || (port->state != EHEA_PORT_UP))
+				continue;
+
+			for (l = 0;
+			     l < port->num_def_qps + port->num_add_tx_qps;
+			     l++) {
+				struct ehea_port_res *pr = &port->port_res[l];
+
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->qp->fw_handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->send_cq->fw_handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->recv_cq->fw_handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->eq->fw_handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->send_mr.handle;
+				arr[i].adh = adapter->handle;
+				arr[i++].fwh = pr->recv_mr.handle;
+			}
+			arr[i].adh = adapter->handle;
+			arr[i++].fwh = port->qp_eq->fw_handle;
+		}
+
+		arr[i].adh = adapter->handle;
+		arr[i++].fwh = adapter->neq->fw_handle;
+
+		if (adapter->mr.handle) {
+			arr[i].adh = adapter->handle;
+			arr[i++].fwh = adapter->mr.handle;
+		}
+	}
+
+out_update:
+	kfree(ehea_fw_handles.arr);
+	ehea_fw_handles.arr = arr;
+	ehea_fw_handles.num_entries = i;
+}
+
+static void ehea_update_bcmc_registrations(void)
+{
+	struct ehea_bcmc_reg_entry *arr = NULL;
+	struct ehea_adapter *adapter;
+	struct ehea_mc_list *mc_entry;
+	int num_registrations = 0;
+	int i = 0;
+	int k;
+
+	/* Determine number of registrations */
+	list_for_each_entry(adapter, &adapter_list, list)
+		for (k = 0; k < EHEA_MAX_PORTS; k++) {
+			struct ehea_port *port = adapter->port[k];
+
+			if (!port || (port->state != EHEA_PORT_UP))
+				continue;
+
+			num_registrations += 2;	/* Broadcast registrations */
+
+			list_for_each_entry(mc_entry, &port->mc_list->list,list)
+				num_registrations += 2;
+		}
+
+	if (num_registrations) {
+		arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL);
+		if (!arr)
+			return;  /* Keep the existing array */
+	} else
+		goto out_update;
+
+	list_for_each_entry(adapter, &adapter_list, list) {
+		for (k = 0; k < EHEA_MAX_PORTS; k++) {
+			struct ehea_port *port = adapter->port[k];
+
+			if (!port || (port->state != EHEA_PORT_UP))
+				continue;
+
+			arr[i].adh = adapter->handle;
+			arr[i].port_id = port->logical_port_id;
+			arr[i].reg_type = EHEA_BCMC_BROADCAST |
+					  EHEA_BCMC_UNTAGGED;
+			arr[i++].macaddr = port->mac_addr;
+
+			arr[i].adh = adapter->handle;
+			arr[i].port_id = port->logical_port_id;
+			arr[i].reg_type = EHEA_BCMC_BROADCAST |
+					  EHEA_BCMC_VLANID_ALL;
+			arr[i++].macaddr = port->mac_addr;
+
+			list_for_each_entry(mc_entry,
+					    &port->mc_list->list, list) {
+				arr[i].adh = adapter->handle;
+				arr[i].port_id = port->logical_port_id;
+				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+						  EHEA_BCMC_MULTICAST |
+						  EHEA_BCMC_UNTAGGED;
+				arr[i++].macaddr = mc_entry->macaddr;
+
+				arr[i].adh = adapter->handle;
+				arr[i].port_id = port->logical_port_id;
+				arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
+						  EHEA_BCMC_MULTICAST |
+						  EHEA_BCMC_VLANID_ALL;
+				arr[i++].macaddr = mc_entry->macaddr;
+			}
+		}
+	}
+
+out_update:
+	kfree(ehea_bcmc_regs.arr);
+	ehea_bcmc_regs.arr = arr;
+	ehea_bcmc_regs.num_entries = i;
+}
+
 static struct net_device_stats *ehea_get_stats(struct net_device *dev)
 {
 	struct ehea_port *port = netdev_priv(dev);
@@ -1601,19 +1758,25 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
 
 	memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
 
+	down(&ehea_bcmc_regs.lock);
+
 	/* Deregister old MAC in pHYP */
 	ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 	if (ret)
-		goto out_free;
+		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_free;
+		goto out_upregs;
 
 	ret = 0;
+
+out_upregs:
+	ehea_update_bcmc_registrations();
+	up(&ehea_bcmc_regs.lock);
 out_free:
 	kfree(cb0);
 out:
@@ -1775,9 +1938,11 @@ static void ehea_set_multicast_list(struct net_device *dev)
 	}
 	ehea_promiscuous(dev, 0);
 
+	down(&ehea_bcmc_regs.lock);
+
 	if (dev->flags & IFF_ALLMULTI) {
 		ehea_allmulti(dev, 1);
-		return;
+		goto out;
 	}
 	ehea_allmulti(dev, 0);
 
@@ -1803,6 +1968,8 @@ static void ehea_set_multicast_list(struct net_device *dev)
 
 	}
 out:
+	ehea_update_bcmc_registrations();
+	up(&ehea_bcmc_regs.lock);
 	return;
 }
 
@@ -2285,6 +2452,8 @@ static int ehea_up(struct net_device *dev)
 	if (port->state == EHEA_PORT_UP)
 		return 0;
 
+	down(&ehea_fw_handles.lock);
+
 	ret = ehea_port_res_setup(port, port->num_def_qps,
 				  port->num_add_tx_qps);
 	if (ret) {
@@ -2321,8 +2490,17 @@ static int ehea_up(struct net_device *dev)
 		}
 	}
 
-	ret = 0;
+	down(&ehea_bcmc_regs.lock);
+
+	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
+	if (ret) {
+		ret = -EIO;
+		goto out_free_irqs;
+	}
+
 	port->state = EHEA_PORT_UP;
+
+	ret = 0;
 	goto out;
 
 out_free_irqs:
@@ -2334,6 +2512,12 @@ out:
 	if (ret)
 		ehea_info("Failed starting %s. ret=%i", dev->name, ret);
 
+	ehea_update_bcmc_registrations();
+	up(&ehea_bcmc_regs.lock);
+
+	ehea_update_firmware_handles();
+	up(&ehea_fw_handles.lock);
+
 	return ret;
 }
 
@@ -2382,16 +2566,27 @@ static int ehea_down(struct net_device *dev)
 	if (port->state == EHEA_PORT_DOWN)
 		return 0;
 
+	down(&ehea_bcmc_regs.lock);
 	ehea_drop_multicast_list(dev);
+	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
+
 	ehea_free_interrupts(dev);
 
+	down(&ehea_fw_handles.lock);
+
 	port->state = EHEA_PORT_DOWN;
 
+	ehea_update_bcmc_registrations();
+	up(&ehea_bcmc_regs.lock);
+
 	ret = ehea_clean_all_portres(port);
 	if (ret)
 		ehea_info("Failed freeing resources for %s. ret=%i",
 			  dev->name, ret);
 
+	ehea_update_firmware_handles();
+	up(&ehea_fw_handles.lock);
+
 	return ret;
 }
 
@@ -2920,19 +3115,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 	dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
 
 	INIT_WORK(&port->reset_task, ehea_reset_port);
-
-	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
-	if (ret) {
-		ret = -EIO;
-		goto out_unreg_port;
-	}
-
 	ehea_set_ethtool_ops(dev);
 
 	ret = register_netdev(dev);
 	if (ret) {
 		ehea_error("register_netdev failed. ret=%d", ret);
-		goto out_dereg_bc;
+		goto out_unreg_port;
 	}
 
 	port->lro_max_aggr = lro_max_aggr;
@@ -2949,9 +3137,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 
 	return port;
 
-out_dereg_bc:
-	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
-
 out_unreg_port:
 	ehea_unregister_port(port);
 
@@ -2971,7 +3156,6 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
 {
 	unregister_netdev(port->netdev);
 	ehea_unregister_port(port);
-	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 	kfree(port->mc_list);
 	free_netdev(port->netdev);
 	port->adapter->active_ports--;
@@ -3014,7 +3198,6 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
 
 		i++;
 	};
-
 	return 0;
 }
 
@@ -3159,6 +3342,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
 		ehea_error("Invalid ibmebus device probed");
 		return -EINVAL;
 	}
+	down(&ehea_fw_handles.lock);
 
 	adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
 	if (!adapter) {
@@ -3239,7 +3423,10 @@ out_kill_eq:
 
 out_free_ad:
 	kfree(adapter);
+
 out:
+	ehea_update_firmware_handles();
+	up(&ehea_fw_handles.lock);
 	return ret;
 }
 
@@ -3258,18 +3445,41 @@ static int __devexit ehea_remove(struct of_device *dev)
 
 	flush_scheduled_work();
 
+	down(&ehea_fw_handles.lock);
+
 	ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
 	tasklet_kill(&adapter->neq_tasklet);
 
 	ehea_destroy_eq(adapter->neq);
 	ehea_remove_adapter_mr(adapter);
 	list_del(&adapter->list);
-
 	kfree(adapter);
 
+	ehea_update_firmware_handles();
+	up(&ehea_fw_handles.lock);
+
 	return 0;
 }
 
+void ehea_crash_handler(void)
+{
+	int i;
+
+	if (ehea_fw_handles.arr)
+		for (i = 0; i < ehea_fw_handles.num_entries; i++)
+			ehea_h_free_resource(ehea_fw_handles.arr[i].adh,
+					     ehea_fw_handles.arr[i].fwh,
+					     FORCE_FREE);
+
+	if (ehea_bcmc_regs.arr)
+		for (i = 0; i < ehea_bcmc_regs.num_entries; i++)
+			ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh,
+					      ehea_bcmc_regs.arr[i].port_id,
+					      ehea_bcmc_regs.arr[i].reg_type,
+					      ehea_bcmc_regs.arr[i].macaddr,
+					      0, H_DEREG_BCMC);
+}
+
 static int ehea_reboot_notifier(struct notifier_block *nb,
 				unsigned long action, void *unused)
 {
@@ -3330,7 +3540,12 @@ int __init ehea_module_init(void)
 
 
 	INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
+	memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles));
+	memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
+
 	sema_init(&dlpar_mem_lock, 1);
+	sema_init(&ehea_fw_handles.lock, 1);
+	sema_init(&ehea_bcmc_regs.lock, 1);
 
 	ret = check_module_parm();
 	if (ret)
@@ -3340,12 +3555,18 @@ int __init ehea_module_init(void)
 	if (ret)
 		goto out;
 
-	register_reboot_notifier(&ehea_reboot_nb);
+	ret = register_reboot_notifier(&ehea_reboot_nb);
+	if (ret)
+		ehea_info("failed registering reboot notifier");
+
+	ret = crash_shutdown_register(&ehea_crash_handler);
+	if (ret)
+		ehea_info("failed registering crash handler");
 
 	ret = ibmebus_register_driver(&ehea_driver);
 	if (ret) {
 		ehea_error("failed registering eHEA device driver on ebus");
-		goto out;
+		goto out2;
 	}
 
 	ret = driver_create_file(&ehea_driver.driver,
@@ -3353,21 +3574,33 @@ int __init ehea_module_init(void)
 	if (ret) {
 		ehea_error("failed to register capabilities attribute, ret=%d",
 			   ret);
-		unregister_reboot_notifier(&ehea_reboot_nb);
-		ibmebus_unregister_driver(&ehea_driver);
-		goto out;
+		goto out3;
 	}
 
+	return ret;
+
+out3:
+	ibmebus_unregister_driver(&ehea_driver);
+out2:
+	unregister_reboot_notifier(&ehea_reboot_nb);
+	crash_shutdown_unregister(&ehea_crash_handler);
 out:
 	return ret;
 }
 
 static void __exit ehea_module_exit(void)
 {
+	int ret;
+
 	flush_scheduled_work();
 	driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
 	ibmebus_unregister_driver(&ehea_driver);
 	unregister_reboot_notifier(&ehea_reboot_nb);
+	ret = crash_shutdown_unregister(&ehea_crash_handler);
+	if (ret)
+		ehea_info("failed unregistering crash handler");
+	kfree(ehea_fw_handles.arr);
+	kfree(ehea_bcmc_regs.arr);
 	ehea_destroy_busmap();
 }
 
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 42d94ed..af869cf 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -946,16 +946,11 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 	struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data;
-	unsigned long flags;
-	int rc;
 
 	if (!netif_running(dev))
 		return -EINVAL;
 
-	spin_lock_irqsave(&fep->lock, flags);
-	rc = phy_mii_ioctl(fep->phydev, mii, cmd);
-	spin_unlock_irqrestore(&fep->lock, flags);
-	return rc;
+	return phy_mii_ioctl(fep->phydev, mii, cmd);
 }
 
 extern int fs_mii_connect(struct net_device *dev);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 4244fc2..718cf77 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -605,7 +605,7 @@ void stop_gfar(struct net_device *dev)
 
 	free_skb_resources(priv);
 
-	dma_free_coherent(NULL,
+	dma_free_coherent(&dev->dev,
 			sizeof(struct txbd8)*priv->tx_ring_size
 			+ sizeof(struct rxbd8)*priv->rx_ring_size,
 			priv->tx_bd_base,
@@ -626,7 +626,7 @@ static void free_skb_resources(struct gfar_private *priv)
 	for (i = 0; i < priv->tx_ring_size; i++) {
 
 		if (priv->tx_skbuff[i]) {
-			dma_unmap_single(NULL, txbdp->bufPtr,
+			dma_unmap_single(&priv->dev->dev, txbdp->bufPtr,
 					txbdp->length,
 					DMA_TO_DEVICE);
 			dev_kfree_skb_any(priv->tx_skbuff[i]);
@@ -643,7 +643,7 @@ static void free_skb_resources(struct gfar_private *priv)
 	if(priv->rx_skbuff != NULL) {
 		for (i = 0; i < priv->rx_ring_size; i++) {
 			if (priv->rx_skbuff[i]) {
-				dma_unmap_single(NULL, rxbdp->bufPtr,
+				dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr,
 						priv->rx_buffer_size,
 						DMA_FROM_DEVICE);
 
@@ -708,7 +708,7 @@ int startup_gfar(struct net_device *dev)
 	gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 
 	/* Allocate memory for the buffer descriptors */
-	vaddr = (unsigned long) dma_alloc_coherent(NULL,
+	vaddr = (unsigned long) dma_alloc_coherent(&dev->dev,
 			sizeof (struct txbd8) * priv->tx_ring_size +
 			sizeof (struct rxbd8) * priv->rx_ring_size,
 			&addr, GFP_KERNEL);
@@ -919,7 +919,7 @@ err_irq_fail:
 rx_skb_fail:
 	free_skb_resources(priv);
 tx_skb_fail:
-	dma_free_coherent(NULL,
+	dma_free_coherent(&dev->dev,
 			sizeof(struct txbd8)*priv->tx_ring_size
 			+ sizeof(struct rxbd8)*priv->rx_ring_size,
 			priv->tx_bd_base,
@@ -1053,7 +1053,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* Set buffer length and pointer */
 	txbdp->length = skb->len;
-	txbdp->bufPtr = dma_map_single(NULL, skb->data,
+	txbdp->bufPtr = dma_map_single(&dev->dev, skb->data,
 			skb->len, DMA_TO_DEVICE);
 
 	/* Save the skb pointer so we can free it later */
@@ -1332,7 +1332,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
 	 */
 	skb_reserve(skb, alignamount);
 
-	bdp->bufPtr = dma_map_single(NULL, skb->data,
+	bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
 			priv->rx_buffer_size, DMA_FROM_DEVICE);
 
 	bdp->length = 0;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index bff280e..6a1f230 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -439,7 +439,7 @@ static int igb_request_irq(struct igb_adapter *adapter)
 		err = igb_request_msix(adapter);
 		if (!err) {
 			/* enable IAM, auto-mask,
-			 * DO NOT USE EIAME or IAME in legacy mode */
+			 * DO NOT USE EIAM or IAM in legacy mode */
 			wr32(E1000_IAM, IMS_ENABLE_MASK);
 			goto request_done;
 		}
@@ -465,14 +465,9 @@ static int igb_request_irq(struct igb_adapter *adapter)
 	err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
 			  netdev->name, netdev);
 
-	if (err) {
+	if (err)
 		dev_err(&adapter->pdev->dev, "Error %d getting interrupt\n",
 			err);
-		goto request_done;
-	}
-
-	/* enable IAM, auto-mask */
-	wr32(E1000_IAM, IMS_ENABLE_MASK);
 
 request_done:
 	return err;
@@ -821,7 +816,8 @@ void igb_reset(struct igb_adapter *adapter)
 	wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
 
 	igb_reset_adaptive(&adapter->hw);
-	adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+	if (adapter->hw.phy.ops.get_phy_info)
+		adapter->hw.phy.ops.get_phy_info(&adapter->hw);
 }
 
 /**
@@ -2057,7 +2053,8 @@ static void igb_set_multi(struct net_device *netdev)
 static void igb_update_phy_info(unsigned long data)
 {
 	struct igb_adapter *adapter = (struct igb_adapter *) data;
-	adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+	if (adapter->hw.phy.ops.get_phy_info)
+		adapter->hw.phy.ops.get_phy_info(&adapter->hw);
 }
 
 /**
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 6323988..c1a4139 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -590,6 +590,13 @@ static int pcnet_config(struct pcmcia_device *link)
 	dev->if_port = 0;
     }
 
+    if ((link->conf.ConfigBase == 0x03c0) 
+	&& (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) {
+    	printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
+    	printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
+	goto failed;
+    }
+
     local_hw_info = get_hwinfo(link);
     if (local_hw_info == NULL)
 	local_hw_info = get_prom(link);
@@ -1567,12 +1574,11 @@ static struct pcmcia_device_id pcnet_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145),
 	PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230),
 	PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
-/*	PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), conflict with axnet_cs */
+	PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), 
 	PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
 	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
 	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
 	PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
-/*	PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), conflict with axnet_cs */
 	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
 	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307),
 	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a),
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 6e9f619..963630c 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -49,13 +49,13 @@ int mdiobus_register(struct mii_bus *bus)
 	int i;
 	int err = 0;
 
-	mutex_init(&bus->mdio_lock);
-
 	if (NULL == bus || NULL == bus->name ||
 			NULL == bus->read ||
 			NULL == bus->write)
 		return -EINVAL;
 
+	mutex_init(&bus->mdio_lock);
+
 	if (bus->reset)
 		bus->reset(bus);
 
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 202fdf3..20745fd 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1633,13 +1633,18 @@ static inline void sis190_init_rxfilter(struct net_device *dev)
 static int __devinit sis190_get_mac_addr(struct pci_dev *pdev, 
 					 struct net_device *dev)
 {
-	u8 from;
+	int rc;
+
+	rc = sis190_get_mac_addr_from_eeprom(pdev, dev);
+	if (rc < 0) {
+		u8 reg;
 
-	pci_read_config_byte(pdev, 0x73, &from);
+		pci_read_config_byte(pdev, 0x73, &reg);
 
-	return (from & 0x00000001) ?
-		sis190_get_mac_addr_from_apc(pdev, dev) :
-		sis190_get_mac_addr_from_eeprom(pdev, dev);
+		if (reg & 0x00000001)
+			rc = sis190_get_mac_addr_from_apc(pdev, dev);
+	}
+	return rc;
 }
 
 static void sis190_set_speed_auto(struct net_device *dev)
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 3af5b92..0166407 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -1400,7 +1400,7 @@ static void TLan_SetMulticastList( struct net_device *dev )
 	 *
 	 **************************************************************/
 
-u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
 {
 	/* printk( "TLAN:  Invalid interrupt on %s.\n", dev->name ); */
 	return 0;
@@ -1432,7 +1432,7 @@ u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
 	 *
 	 **************************************************************/
 
-u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	int		eoc = 0;
@@ -1518,7 +1518,7 @@ u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
 	 *
 	 **************************************************************/
 
-u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
 {
 	TLan_ReadAndClearStats( dev, TLAN_RECORD );
 
@@ -1554,7 +1554,7 @@ u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
 	 *
 	 **************************************************************/
 
-u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u32		ack = 0;
@@ -1689,7 +1689,7 @@ u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
 	 *
 	 **************************************************************/
 
-u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
 {
 	printk( "TLAN:  Test interrupt on %s.\n", dev->name );
 	return 1;
@@ -1719,7 +1719,7 @@ u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
 	 *
 	 **************************************************************/
 
-u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	TLanList		*head_list;
@@ -1767,7 +1767,7 @@ u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
 	 *
 	 **************************************************************/
 
-u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u32		ack;
@@ -1842,7 +1842,7 @@ u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
 	 *
 	 **************************************************************/
 
-u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
+static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	dma_addr_t	head_list_phys;
@@ -1902,7 +1902,7 @@ u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
 	 *
 	 **************************************************************/
 
-void TLan_Timer( unsigned long data )
+static void TLan_Timer( unsigned long data )
 {
 	struct net_device	*dev = (struct net_device *) data;
 	TLanPrivateInfo	*priv = netdev_priv(dev);
@@ -1983,7 +1983,7 @@ void TLan_Timer( unsigned long data )
 	 *
 	 **************************************************************/
 
-void TLan_ResetLists( struct net_device *dev )
+static void TLan_ResetLists( struct net_device *dev )
 {
 	TLanPrivateInfo *priv = netdev_priv(dev);
 	int		i;
@@ -2043,7 +2043,7 @@ void TLan_ResetLists( struct net_device *dev )
 } /* TLan_ResetLists */
 
 
-void TLan_FreeLists( struct net_device *dev )
+static void TLan_FreeLists( struct net_device *dev )
 {
 	TLanPrivateInfo *priv = netdev_priv(dev);
 	int		i;
@@ -2092,7 +2092,7 @@ void TLan_FreeLists( struct net_device *dev )
 	 *
 	 **************************************************************/
 
-void TLan_PrintDio( u16 io_base )
+static void TLan_PrintDio( u16 io_base )
 {
 	u32 data0, data1;
 	int	i;
@@ -2127,7 +2127,7 @@ void TLan_PrintDio( u16 io_base )
 	 *
 	 **************************************************************/
 
-void TLan_PrintList( TLanList *list, char *type, int num)
+static void TLan_PrintList( TLanList *list, char *type, int num)
 {
 	int i;
 
@@ -2163,7 +2163,7 @@ void TLan_PrintList( TLanList *list, char *type, int num)
 	 *
 	 **************************************************************/
 
-void TLan_ReadAndClearStats( struct net_device *dev, int record )
+static void TLan_ReadAndClearStats( struct net_device *dev, int record )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u32		tx_good, tx_under;
@@ -2238,7 +2238,7 @@ void TLan_ReadAndClearStats( struct net_device *dev, int record )
 	 *
 	 **************************************************************/
 
-void
+static void
 TLan_ResetAdapter( struct net_device *dev )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
@@ -2324,7 +2324,7 @@ TLan_ResetAdapter( struct net_device *dev )
 
 
 
-void
+static void
 TLan_FinishReset( struct net_device *dev )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
@@ -2448,7 +2448,7 @@ TLan_FinishReset( struct net_device *dev )
 	 *
 	 **************************************************************/
 
-void TLan_SetMac( struct net_device *dev, int areg, char *mac )
+static void TLan_SetMac( struct net_device *dev, int areg, char *mac )
 {
 	int i;
 
@@ -2490,7 +2490,7 @@ void TLan_SetMac( struct net_device *dev, int areg, char *mac )
 	 *
 	 ********************************************************************/
 
-void TLan_PhyPrint( struct net_device *dev )
+static void TLan_PhyPrint( struct net_device *dev )
 {
 	TLanPrivateInfo *priv = netdev_priv(dev);
 	u16 i, data0, data1, data2, data3, phy;
@@ -2539,7 +2539,7 @@ void TLan_PhyPrint( struct net_device *dev )
 	 *
 	 ********************************************************************/
 
-void TLan_PhyDetect( struct net_device *dev )
+static void TLan_PhyDetect( struct net_device *dev )
 {
 	TLanPrivateInfo *priv = netdev_priv(dev);
 	u16		control;
@@ -2586,7 +2586,7 @@ void TLan_PhyDetect( struct net_device *dev )
 
 
 
-void TLan_PhyPowerDown( struct net_device *dev )
+static void TLan_PhyPowerDown( struct net_device *dev )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		value;
@@ -2611,7 +2611,7 @@ void TLan_PhyPowerDown( struct net_device *dev )
 
 
 
-void TLan_PhyPowerUp( struct net_device *dev )
+static void TLan_PhyPowerUp( struct net_device *dev )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		value;
@@ -2632,7 +2632,7 @@ void TLan_PhyPowerUp( struct net_device *dev )
 
 
 
-void TLan_PhyReset( struct net_device *dev )
+static void TLan_PhyReset( struct net_device *dev )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		phy;
@@ -2660,7 +2660,7 @@ void TLan_PhyReset( struct net_device *dev )
 
 
 
-void TLan_PhyStartLink( struct net_device *dev )
+static void TLan_PhyStartLink( struct net_device *dev )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		ability;
@@ -2747,7 +2747,7 @@ void TLan_PhyStartLink( struct net_device *dev )
 
 
 
-void TLan_PhyFinishAutoNeg( struct net_device *dev )
+static void TLan_PhyFinishAutoNeg( struct net_device *dev )
 {
 	TLanPrivateInfo	*priv = netdev_priv(dev);
 	u16		an_adv;
@@ -2903,7 +2903,7 @@ void TLan_PhyMonitor( struct net_device *dev )
 	 *
 	 **************************************************************/
 
-int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
+static int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
 {
 	u8	nack;
 	u16	sio, tmp;
@@ -2993,7 +2993,7 @@ int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
 	 *
 	 **************************************************************/
 
-void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
+static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
 {
 	u16 sio;
 	u32 i;
@@ -3035,7 +3035,7 @@ void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
 	 *
 	 **************************************************************/
 
-void TLan_MiiSync( u16 base_port )
+static void TLan_MiiSync( u16 base_port )
 {
 	int i;
 	u16 sio;
@@ -3074,7 +3074,7 @@ void TLan_MiiSync( u16 base_port )
 	 *
 	 **************************************************************/
 
-void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
+static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
 {
 	u16	sio;
 	int	minten;
@@ -3144,7 +3144,7 @@ void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
 	 *
 	 **************************************************************/
 
-void TLan_EeSendStart( u16 io_base )
+static void TLan_EeSendStart( u16 io_base )
 {
 	u16	sio;
 
@@ -3184,7 +3184,7 @@ void TLan_EeSendStart( u16 io_base )
 	 *
 	 **************************************************************/
 
-int TLan_EeSendByte( u16 io_base, u8 data, int stop )
+static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
 {
 	int	err;
 	u8	place;
@@ -3245,7 +3245,7 @@ int TLan_EeSendByte( u16 io_base, u8 data, int stop )
 	 *
 	 **************************************************************/
 
-void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
+static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
 {
 	u8  place;
 	u16 sio;
@@ -3303,7 +3303,7 @@ void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
 	 *
 	 **************************************************************/
 
-int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
+static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
 {
 	int err;
 	TLanPrivateInfo *priv = netdev_priv(dev);
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index a7afeea..a59c1f2 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -482,9 +482,11 @@ static void uli526x_init(struct net_device *dev)
 	struct uli526x_board_info *db = netdev_priv(dev);
 	unsigned long ioaddr = db->ioaddr;
 	u8	phy_tmp;
+	u8	timeout;
 	u16	phy_value;
 	u16 phy_reg_reset;
 
+
 	ULI526X_DBUG(0, "uli526x_init()", 0);
 
 	/* Reset M526x MAC controller */
@@ -509,11 +511,19 @@ static void uli526x_init(struct net_device *dev)
 	/* Parser SROM and media mode */
 	db->media_mode = uli526x_media_mode;
 
-	/* Phyxcer capability setting */
+	/* phyxcer capability setting */
 	phy_reg_reset = phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id);
 	phy_reg_reset = (phy_reg_reset | 0x8000);
 	phy_write(db->ioaddr, db->phy_addr, 0, phy_reg_reset, db->chip_id);
+
+	/* See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management
+	 * functions") or phy data sheet for details on phy reset
+	 */
 	udelay(500);
+	timeout = 10;
+	while (timeout-- &&
+		phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id) & 0x8000)
+			udelay(100);
 
 	/* Process Phyxcer Media Mode */
 	uli526x_set_phyxcer(db);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fdc2367..19fd4cb 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -361,6 +361,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 	netif_napi_add(dev, &vi->napi, virtnet_poll, napi_weight);
 	vi->dev = dev;
 	vi->vdev = vdev;
+	vdev->priv = vi;
 
 	/* We expect two virtqueues, receive then send. */
 	vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
@@ -395,7 +396,6 @@ static int virtnet_probe(struct virtio_device *vdev)
 	}
 
 	pr_debug("virtnet: registered device %s\n", dev->name);
-	vdev->priv = vi;
 	return 0;
 
 unregister:
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index c307621..d8a5c22 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -1851,8 +1851,7 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
                 }
         }
         /*      See how many write buffers are required to hold this data */
-        numBuffers= ( skb->len + privptr->p_env->write_size - 1) /
-			( privptr->p_env->write_size);
+	numBuffers = DIV_ROUND_UP(skb->len, privptr->p_env->write_size);
 
         /*      If that number of buffers isn't available, give up for now */
         if (privptr->write_free_count < numBuffers ||
@@ -2114,8 +2113,7 @@ init_ccw_bk(struct net_device *dev)
         */
         ccw_blocks_perpage= PAGE_SIZE /  CCWBK_SIZE;
         ccw_pages_required=
-		(ccw_blocks_required+ccw_blocks_perpage -1) /
-			 ccw_blocks_perpage;
+		DIV_ROUND_UP(ccw_blocks_required, ccw_blocks_perpage);
 
 #ifdef DEBUGMSG
         printk(KERN_INFO "%s: %s() > ccw_blocks_perpage=%d\n",
@@ -2131,30 +2129,29 @@ init_ccw_bk(struct net_device *dev)
 	 * provide good performance. With packing buffers support 32k
 	 * buffers are used.
          */
-        if (privptr->p_env->read_size < PAGE_SIZE) {
-            claw_reads_perpage= PAGE_SIZE / privptr->p_env->read_size;
-            claw_read_pages= (privptr->p_env->read_buffers +
-	    	claw_reads_perpage -1) / claw_reads_perpage;
+	if (privptr->p_env->read_size < PAGE_SIZE) {
+		claw_reads_perpage = PAGE_SIZE / privptr->p_env->read_size;
+		claw_read_pages = DIV_ROUND_UP(privptr->p_env->read_buffers,
+						claw_reads_perpage);
          }
          else {       /* > or equal  */
-            privptr->p_buff_pages_perread=
-	    	(privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE;
-            claw_read_pages=
-	    	privptr->p_env->read_buffers * privptr->p_buff_pages_perread;
+		privptr->p_buff_pages_perread =
+			DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE);
+		claw_read_pages = privptr->p_env->read_buffers *
+					privptr->p_buff_pages_perread;
          }
         if (privptr->p_env->write_size < PAGE_SIZE) {
-            claw_writes_perpage=
-	    	PAGE_SIZE / privptr->p_env->write_size;
-            claw_write_pages=
-	    	(privptr->p_env->write_buffers + claw_writes_perpage -1) /
-			claw_writes_perpage;
+		claw_writes_perpage =
+			PAGE_SIZE / privptr->p_env->write_size;
+		claw_write_pages = DIV_ROUND_UP(privptr->p_env->write_buffers,
+						claw_writes_perpage);
 
         }
         else {      /* >  or equal  */
-            privptr->p_buff_pages_perwrite=
-	    	 (privptr->p_env->read_size + PAGE_SIZE - 1) / PAGE_SIZE;
-            claw_write_pages=
-	     	privptr->p_env->write_buffers * privptr->p_buff_pages_perwrite;
+		privptr->p_buff_pages_perwrite =
+			DIV_ROUND_UP(privptr->p_env->read_size, PAGE_SIZE);
+		claw_write_pages = privptr->p_env->write_buffers *
+					privptr->p_buff_pages_perwrite;
         }
 #ifdef DEBUGMSG
         if (privptr->p_env->read_size < PAGE_SIZE) {

^ permalink raw reply related

* Re: [2.6 patch] net/phy/mdio_bus.c: fix a check-after-use
From: Jeff Garzik @ 2008-02-20 16:52 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: netdev, linux-kernel
In-Reply-To: <20080220001353.GV31955@cs181133002.pp.htv.fi>

Adrian Bunk wrote:
> This patch fixes a check-after-use spotted by the Coverity checker.
> 
> Signed-off-by: Adrian Bunk <bunk@kernel.org>
> 
> ---
> 6beeb3ac577d74d72b2f91bd654eecb904c3c17e diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
> index 6e9f619..963630c 100644
> --- a/drivers/net/phy/mdio_bus.c
> +++ b/drivers/net/phy/mdio_bus.c
> @@ -49,13 +49,13 @@ int mdiobus_register(struct mii_bus *bus)
>  	int i;
>  	int err = 0;
>  
> -	mutex_init(&bus->mdio_lock);
> -
>  	if (NULL == bus || NULL == bus->name ||
>  			NULL == bus->read ||
>  			NULL == bus->write)
>  		return -EINVAL;
>  
> +	mutex_init(&bus->mdio_lock);
> +

applied



^ permalink raw reply

* Re: [PATCH] igb: Fix panic with NICs with 1000BASE-SX PHY
From: Jeff Garzik @ 2008-02-20 16:52 UTC (permalink / raw)
  To: Auke Kok; +Cc: e1000-devel, netdev, bill.hayes, andy
In-Reply-To: <20080219182441.12033.64731.stgit@localhost.localdomain>

Auke Kok wrote:
> From: Bill Hayes <bill.hayes@hp.com>
> 
> This patch eliminates a kernel panic with the igb driver in 2.6.25-rc2 when 
> running on a Intel 82575 Ethernet controller with a 1000BASE-SX PHY.  The 
> panic does not happen with the 1000BASE-T PHY, only with a SX connection.  
> 
> Signed-off-by: Bill Hayes <bill.hayes@hp.com>
> Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>

applied



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply

* Re: [PATCH v2.6.25] gianfar: don't pass NULL dev ptr to DMA ops
From: Jeff Garzik @ 2008-02-20 16:52 UTC (permalink / raw)
  To: Andy Fleming; +Cc: netdev, Becky Bruce, Becky Bruce
In-Reply-To: <1203377070-19870-1-git-send-email-afleming@freescale.com>

Andy Fleming wrote:
> From: Becky Bruce <bgill@freescale.com>
> 
> Change all dma op invocations in gianfar.c to actually pass in the
> device pointer.  Currently, the value is ignored, but it will be
> used going forward as we implement archdata for 32-bit powerpc.
> 
> Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
> Acked-by: Andy Fleming <afleming@freescale.com>
> ---
>  drivers/net/gianfar.c |   14 +++++++-------
>  1 files changed, 7 insertions(+), 7 deletions(-)

applied



^ permalink raw reply

* Re: [PATCH 1/1] sis190: read the mac address from the eeprom first
From: Jeff Garzik @ 2008-02-20 16:52 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev, Andrew Morton, dsd, Gabriel A. Devenyi
In-Reply-To: <20080218202032.GA2565@electric-eye.fr.zoreil.com>

Francois Romieu wrote:
> Reading a serie of zero from the cmos sram area do not work
> well with is_valid_ether_addr(). Let's read the mac address
> from the eeprom first as it seems more reliable.
> 
> Fix for http://bugzilla.kernel.org/show_bug.cgi?id=9831
> 
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> ---
>  drivers/net/sis190.c |   15 ++++++++++-----
>  1 files changed, 10 insertions(+), 5 deletions(-)

applied



^ permalink raw reply

* Re: [PATCH] tlan: add static to function definitions
From: Jeff Garzik @ 2008-02-20 16:51 UTC (permalink / raw)
  To: Harvey Harrison; +Cc: Samuel Chessman, LKML, linux-netdev
In-Reply-To: <1203357878.5757.26.camel@brick>

Harvey Harrison wrote:
> The forward declarations were already marked static, make the definitions
> be static as well.  Fixes the sparse warnings as well.
> 
> drivers/net/tlan.c:1403:5: warning: symbol 'TLan_HandleInvalid' was not declared. Should it be static?
> drivers/net/tlan.c:1435:5: warning: symbol 'TLan_HandleTxEOF' was not declared. Should it be static?
> drivers/net/tlan.c:1521:5: warning: symbol 'TLan_HandleStatOverflow' was not declared. Should it be static?
> drivers/net/tlan.c:1557:5: warning: symbol 'TLan_HandleRxEOF' was not declared. Should it be static?
> drivers/net/tlan.c:1692:5: warning: symbol 'TLan_HandleDummy' was not declared. Should it be static?
> drivers/net/tlan.c:1722:5: warning: symbol 'TLan_HandleTxEOC' was not declared. Should it be static?
> drivers/net/tlan.c:1770:5: warning: symbol 'TLan_HandleStatusCheck' was not declared. Should it be static?
> drivers/net/tlan.c:1845:5: warning: symbol 'TLan_HandleRxEOC' was not declared. Should it be static?
> drivers/net/tlan.c:1905:6: warning: symbol 'TLan_Timer' was not declared. Should it be static?
> drivers/net/tlan.c:1986:6: warning: symbol 'TLan_ResetLists' was not declared. Should it be static?
> drivers/net/tlan.c:2046:6: warning: symbol 'TLan_FreeLists' was not declared. Should it be static?
> drivers/net/tlan.c:2095:6: warning: symbol 'TLan_PrintDio' was not declared. Should it be static?
> drivers/net/tlan.c:2130:6: warning: symbol 'TLan_PrintList' was not declared. Should it be static?
> drivers/net/tlan.c:2166:6: warning: symbol 'TLan_ReadAndClearStats' was not declared. Should it be static?
> drivers/net/tlan.c:2242:1: warning: symbol 'TLan_ResetAdapter' was not declared. Should it be static?
> drivers/net/tlan.c:2328:1: warning: symbol 'TLan_FinishReset' was not declared. Should it be static?
> drivers/net/tlan.c:2451:6: warning: symbol 'TLan_SetMac' was not declared. Should it be static?
> drivers/net/tlan.c:2493:6: warning: symbol 'TLan_PhyPrint' was not declared. Should it be static?
> drivers/net/tlan.c:2542:6: warning: symbol 'TLan_PhyDetect' was not declared. Should it be static?
> drivers/net/tlan.c:2589:6: warning: symbol 'TLan_PhyPowerDown' was not declared. Should it be static?
> drivers/net/tlan.c:2614:6: warning: symbol 'TLan_PhyPowerUp' was not declared. Should it be static?
> drivers/net/tlan.c:2635:6: warning: symbol 'TLan_PhyReset' was not declared. Should it be static?
> drivers/net/tlan.c:2663:6: warning: symbol 'TLan_PhyStartLink' was not declared. Should it be static?
> drivers/net/tlan.c:2750:6: warning: symbol 'TLan_PhyFinishAutoNeg' was not declared. Should it be static?
> drivers/net/tlan.c:2906:5: warning: symbol 'TLan_MiiReadReg' was not declared. Should it be static?
> drivers/net/tlan.c:2996:6: warning: symbol 'TLan_MiiSendData' was not declared. Should it be static?
> drivers/net/tlan.c:3038:6: warning: symbol 'TLan_MiiSync' was not declared. Should it be static?
> drivers/net/tlan.c:3077:6: warning: symbol 'TLan_MiiWriteReg' was not declared. Should it be static?
> drivers/net/tlan.c:3147:6: warning: symbol 'TLan_EeSendStart' was not declared. Should it be static?
> drivers/net/tlan.c:3187:5: warning: symbol 'TLan_EeSendByte' was not declared. Should it be static?
> drivers/net/tlan.c:3248:6: warning: symbol 'TLan_EeReceiveByte' was not declared. Should it be static?
> drivers/net/tlan.c:3306:5: warning: symbol 'TLan_EeReadByte' was not declared. Should it be static?
> 
> Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
> ---
> Kept the style consistent with the rest of the file, checkpatch will complain.
>  drivers/net/tlan.c |   64 ++++++++++++++++++++++++++--------------------------
>  1 files changed, 32 insertions(+), 32 deletions(-)

applied



^ permalink raw reply

* Re: [patch 1/1] claw: make use of DIV_ROUND_UP
From: Jeff Garzik @ 2008-02-20 16:51 UTC (permalink / raw)
  To: Ursula Braun; +Cc: netdev, linux-s390, julia
In-Reply-To: <20080218134803.497224000@linux.vnet.ibm.com>

applied


^ permalink raw reply

* Re: [PATCH resend] virtio_net: Fix oops on early interrupts - introduced by virtio reset code
From: Jeff Garzik @ 2008-02-20 16:51 UTC (permalink / raw)
  To: Christian Borntraeger; +Cc: virtualization, netdev
In-Reply-To: <200802181002.51645.borntraeger@de.ibm.com>

Christian Borntraeger wrote:
> Am Montag, 11. Februar 2008 schrieb Anthony Liguori:
>> The reset support is in Linus's tree so we should try to push it for -rc2.
> 
> You are right. My repository was borked. will push it to Jeff Garzik. Thanks
> 
> Jeff can you schedule this fix into your network driver updates? Thanks
> ---
> 
> 
> With the latest virtio_reset patches I got the following oops:
> 
> Unable to handle kernel pointer dereference at virtual kernel address 0000000000000000
> Oops: 0004 [#1] PREEMPT SMP
> Modules linked in:
> CPU: 1 Not tainted 2.6.24zlive-guest-10577-g63f5307-dirty #168
> Process swapper (pid: 0, task: 000000000f866040, ksp: 000000000f86fd78)
> Krnl PSW : 0404100180000000 000000000047598a (skb_recv_done+0x52/0x98)
>            R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:0 CC:1 PM:0 EA:3
> Krnl GPRS: 0000000000000001 0000000000000000 000000000efd0e60 0000000000000001
>            0000000000000000 000000000f866040 0000000000000000 0000000000000000
>            00000000008de4c8 0000000000001237 0000000000001237 000000000f977dd8
>            0000000000000020 00000000001132bc 000000000f977e08 000000000f977dd8
> Krnl Code: 000000000047597c: e31040300004       lg      %r1,48(%r4)
>            0000000000475982: b9040001           lgr     %r0,%r1
>            0000000000475986: b9810003           ogr     %r0,%r3
>           >000000000047598a: eb1040300030       csg     %r1,%r0,48(%r4)
>            0000000000475990: a744fff9           brc     4,475982
>            0000000000475994: a7110001           tmll    %r1,1
>            0000000000475998: a7840009           brc     8,4759aa
>            000000000047599c: e340b0b80004       lg      %r4,184(%r11)
> Call Trace:
> ([<000001500f978000>] 0x1500f978000)
>  [<00000000004779a6>] vring_interrupt+0x72/0x88
>  [<0000000000491d9c>] kvm_extint_handler+0x34/0x44
>  [<000000000010d2d4>] do_extint+0xc0/0xfc
>  [<0000000000113b5a>] ext_no_vtime+0x1c/0x20
>  [<000000000010a0b6>] cpu_idle+0x21a/0x230
> ([<000000000010a096>] cpu_idle+0x1fa/0x230)
>  [<000000000057dfe4>] start_secondary+0xa0/0xb4
> 
> We must initialize vdev->priv before we use the notify hypercall as 
> vdev->priv is used in skb_recv_done. So lets move the assignment of 
> vdev->priv before we call try_fill_recv.
> 
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Acked-by: Anthony Liguori <aliguori@us.ibm.com>
> 
> ---
>  drivers/net/virtio_net.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

applied



^ permalink raw reply

* Re: [PATCH] update TULIP MAINTAINERS
From: Jeff Garzik @ 2008-02-20 16:51 UTC (permalink / raw)
  To: Grant Grundler; +Cc: jgarzik, netdev, kyle, akpm
In-Reply-To: <20080217185349.GC4402@colo.lackof.org>

Grant Grundler wrote:
> Jeff,
> Kyle and I are co-maintaining tulip driver. Normally kyle will review
> my patchs and submit them. I'll deal with bugzilla.kernel.org bugs and
> try to resolve those bugs.
> 
> thanks,
> grant
> 
> Signed-off-by: Grant Grundler <grundler@parisc-linux.org>

applied this and the uli patch



^ permalink raw reply

* Re: [PATCH] igb: fix legacy mode irq issue
From: Jeff Garzik @ 2008-02-20 16:50 UTC (permalink / raw)
  To: Auke Kok; +Cc: e1000-devel, netdev, andy
In-Reply-To: <20080215220525.28483.30217.stgit@localhost.localdomain>

Auke Kok wrote:
> From: Andy Gospodarek <andy@greyhouse.net>
> 
> I booted an igb kernel with the option pci=nomsi and instantly noticed
> that interrupts no longer worked on my igb device.  I took a look at the
> interrupt initialization and quickly discovered a comment stating:
> 
> "DO NOT USE EIAME or IAME in legacy mode"
> 
> It seemed a bit odd that bits to enable IAM were being set in legacy
> interrupt mode, so I dropped out the following parts and interrupts
> began working fine again.
> 
> [Updated code flow and a nitpick spelling error --Auke]
> 
> Signed-off-by: Andy Gospodarek <andy@greyhouse.net>
> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>

applied



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

^ permalink raw reply

* Re: [PATCH] fs_enet: Don't call phy_mii_ioctl() in atomic context.
From: Jeff Garzik @ 2008-02-20 16:50 UTC (permalink / raw)
  To: Scott Wood; +Cc: netdev, linuxppc-dev, Rune Torgersen
In-Reply-To: <20080215210804.GA14468@loki.buserror.net>

Scott Wood wrote:
> The lock acquisition in fs_ioctl() does not appear to actually be necessary,
> and thus is simply removed.
> 
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> This fixes the following bug:
> http://ozlabs.org/pipermail/linuxppc-dev/2008-February/051564.html
> 
>  drivers/net/fs_enet/fs_enet-main.c |    7 +------
>  1 files changed, 1 insertions(+), 6 deletions(-)

applied



^ permalink raw reply

* Re: [PATCH] ehea: add kdump support
From: Jeff Garzik @ 2008-02-20 16:50 UTC (permalink / raw)
  To: Thomas Klein
  Cc: netdev, Christoph Raisch, Jan-Bernd Themann, linux-kernel,
	linux-ppc, Marcus Eder, Thomas Klein
In-Reply-To: <47B30A49.8080404@de.ibm.com>

Thomas Klein wrote:
> This patch adds kdump support to the ehea driver. As the firmware doesn't free
> resource handles automatically, the driver has to run an as simple as possible
> free resource function in case of a crash shutdown. The function iterates over
> two arrays freeing all resource handles which are stored there. The arrays are
> kept up-to-date during normal runtime. The crash handler fn is triggered by the
> recently introduced PPC crash shutdown reg/unreg functions.
> 
> 
> Signed-off-by: Thomas Klein <tklein@de.ibm.com>
> 
> ---
>  drivers/net/ehea/ehea.h      |   34 +++++-
>  drivers/net/ehea/ehea_main.c |  281 ++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 290 insertions(+), 25 deletions(-)

applied



^ permalink raw reply

* Re: [PATCH 22/28] mm: add support for non block device backed swap files
From: Peter Zijlstra @ 2008-02-20 16:46 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Linus Torvalds, Andrew Morton, linux-kernel, linux-mm, netdev,
	trond.myklebust
In-Reply-To: <20080220083046.a3ab16d3.randy.dunlap@oracle.com>


On Wed, 2008-02-20 at 08:30 -0800, Randy Dunlap wrote:
> On Wed, 20 Feb 2008 15:46:32 +0100 Peter Zijlstra wrote:

< grammar mistakes >

Thanks Randy!


^ permalink raw reply

* Re: [PATCH] SUNRPC: Mark buffer used for debug printks with __maybe_unused
From: Joe Perches @ 2008-02-20 16:36 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Pavel Emelyanov, J. Bruce Fields, Linux Netdev List
In-Reply-To: <47BC48C6.3050208@trash.net>

On Wed, 2008-02-20 at 16:35 +0100, Patrick McHardy wrote:
> Alternatively change the dprintk macro to behave similar like
> pr_debug() and mark things like svc_print_addr() __pure, which
> has the advantage that is still performs format checking even
> if debugging is disabled.

I think it's better to change the dprintk style macros
to what Philip Craig suggested.

http://marc.info/?l=linux-wireless&m=120338413108120&w=2

This makes clear to the compiler that the called function is not
going to be used so it can be optimized away, keeps any argument
verification in place, and doesn't require __pure attributes on
arbitrary functions that may be called during the dprintk

#ifdef DEBUG
#define some_print_wrapper(fmt, arg...) \
        do { if (0) printk(KERN_DEBUG fmt, ##arg); } while (0)
#else
#define some_print_wrapper(fmt, arg...) \
	printk(KERN_DEBUG fmt, ##arg)
#endif


^ permalink raw reply

* Re: [PATCH 22/28] mm: add support for non block device backed swap files
From: Randy Dunlap @ 2008-02-20 16:30 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Linus Torvalds, Andrew Morton, linux-kernel, linux-mm, netdev,
	trond.myklebust
In-Reply-To: <20080220150308.142619000@chello.nl>

On Wed, 20 Feb 2008 15:46:32 +0100 Peter Zijlstra wrote:

> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
>  Documentation/filesystems/Locking |   19 +++++++++++++
>  Documentation/filesystems/vfs.txt |   17 ++++++++++++
>  include/linux/buffer_head.h       |    2 -
>  include/linux/fs.h                |    8 +++++
>  include/linux/swap.h              |    4 ++
>  mm/page_io.c                      |   52 ++++++++++++++++++++++++++++++++++++++
>  mm/swap_state.c                   |    4 +-
>  mm/swapfile.c                     |   26 ++++++++++++++++++-
>  8 files changed, 128 insertions(+), 4 deletions(-)

> Index: linux-2.6/Documentation/filesystems/Locking
> ===================================================================
> --- linux-2.6.orig/Documentation/filesystems/Locking
> +++ linux-2.6/Documentation/filesystems/Locking

> @@ -291,6 +297,19 @@ cleaned, or an error value if not. Note 
>  getting mapped back in and redirtied, it needs to be kept locked
>  across the entire operation.
>  
> +	->swapfile() will be called with a non zero argument on address spaces

                                           non-zero

> +backing non block device backed swapfiles. A return value of zero indicates
> +success. In which case this address space can be used for backing swapspace.

   success, in which case

> +The swapspace operations will be proxied to the address space operations.
> +Swapoff will call this method with a zero argument to release the address
> +space.
> +
> +	->swap_out() when swapfile() returned success, this method is used to
> +write the swap page.
> +
> +	->swap_in() when swapfile() returned success, this method is used to
> +read the swap page.
> +
>  	Note: currently almost all instances of address_space methods are
>  using BKL for internal serialization and that's one of the worst sources
>  of contention. Normally they are calling library functions (in fs/buffer.c)

> Index: linux-2.6/Documentation/filesystems/vfs.txt
> ===================================================================
> --- linux-2.6.orig/Documentation/filesystems/vfs.txt
> +++ linux-2.6/Documentation/filesystems/vfs.txt
> @@ -728,6 +732,19 @@ struct address_space_operations {
>    	prevent redirtying the page, it is kept locked during the whole
>  	operation.
>  
> +  swapfile: Called with a non-zero argument when swapon is used on a file. A
> +	return value of zero indicates success. In which case this

                                       success, in which case this

> +	address_space can be used to back swapspace. The swapspace operations
> +	will be proxied to this address space's ->swap_{out,in} methods.
> +	Swapoff will call this method with a zero argument to release the
> +	address space.
> +
> +  swap_out: Called to write a swapcache page to a backing store, similar to
> +	writepage.
> +
> +  swap_in: Called to read a swapcache page from a backing store, similar to
> +	readpage.
> +
>  The File Object
>  ===============

---
~Randy

^ permalink raw reply

* Re: [RFC PATCH 3/8] [NET]: uninline dev_alloc_skb, de-bloats a lot
From: Jan Engelhardt @ 2008-02-20 16:30 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: Ilpo Järvinen, netdev, linux-kernel, David Miller,
	Arnaldo Carvalho de Melo
In-Reply-To: <47BC54FB.2050508@trash.net>


On Feb 20 2008 17:27, Patrick McHardy wrote:
>> Striking. How can this even happen? A callsite which calls
>> 
>>  dev_alloc_skb(n)
>> 
>> is just equivalent to
>> 
>>  __dev_alloc_skb(n, GFP_ATOMIC);
>> 
>> which means there's like 4 (or 8 if it's long) bytes more on the
>> stack. For a worst case, count in another 8 bytes for push and pop or mov on
>> the stack. But that still does not add up to 23 kb.
>
> __dev_alloc_skb() is also an inline function which performs
> some extra work. Which raises the question - if dev_alloc_skb()
> is uninlined, shouldn't __dev_alloc_skb() be uninline as well?
>
I'd like to see the results when {__dev_alloc_skb is externed
and dev_alloc_skb remains inlined}.

^ permalink raw reply

* [PATCH] SUNRPC: Compile out bufs for debug printks
From: Pavel Emelyanov @ 2008-02-20 16:30 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Joe Perches, Linux Netdev List

There are many places, which declare the char buf[...] on the stack
to push it later into dprintk(). Since the dprintk sometimes (if the 
CONFIG_SYSCTL=n) becomes an empty do { } while (0) stub, these buffers
cause gcc to produce appropriate warnings.

Introduce a macro that declares that buf as __maybe_unused.

More candidates for patching are found by Joe Perches.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

---

diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 0822646..b7e179e 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -153,7 +153,7 @@ lockd(struct svc_rqst *rqstp)
 	 */
 	while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) {
 		long timeout = MAX_SCHEDULE_TIMEOUT;
-		char buf[RPC_MAX_ADDRBUFLEN];
+		DECLARE_RPC_BUF(buf);
 
 		if (signalled()) {
 			flush_signals(current);
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 385437e..5643f44 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -436,7 +436,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 	dprintk("lockd: SM_NOTIFY     called\n");
 	if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
 	 || ntohs(saddr.sin_port) >= 1024) {
-		char buf[RPC_MAX_ADDRBUFLEN];
+		DECLARE_RPC_BUF(buf);
 		printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
 				svc_print_addr(rqstp, buf, sizeof(buf)));
 		return rpc_system_err;
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 88379cc..5f0cf50 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -468,7 +468,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 	dprintk("lockd: SM_NOTIFY     called\n");
 	if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK)
 	 || ntohs(saddr.sin_port) >= 1024) {
-		char buf[RPC_MAX_ADDRBUFLEN];
+		DECLARE_RPC_BUF(buf);
 		printk(KERN_WARNING "lockd: rejected NSM callback from %s\n",
 				svc_print_addr(rqstp, buf, sizeof(buf)));
 		return rpc_system_err;
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index bd185a5..33950dc 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -165,7 +165,7 @@ void nfs_callback_down(void)
 static int nfs_callback_authenticate(struct svc_rqst *rqstp)
 {
 	struct nfs_client *clp;
-	char buf[RPC_MAX_ADDRBUFLEN];
+	DECLARE_RPC_BUF(buf);
 
 	/* Don't talk to strangers */
 	clp = nfs_find_client(svc_addr(rqstp), 4);
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 8fbd2dc..94fe70e 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -101,7 +101,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
 {
 	/* Check if the request originated from a secure port. */
 	if (!rqstp->rq_secure && EX_SECURE(exp)) {
-		char buf[RPC_MAX_ADDRBUFLEN];
+		DECLARE_RPC_BUF(buf);
 		dprintk(KERN_WARNING
 		       "nfsd: request from insecure port %s!\n",
 		       svc_print_addr(rqstp, buf, sizeof(buf)));
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 977a71f..66383ae 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -148,7 +148,7 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
 	 */
 
 	if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {
-		char buf[RPC_MAX_ADDRBUFLEN];
+		DECLARE_RPC_BUF(buf);
 		printk(KERN_NOTICE
 			"oversized read request from %s (%d bytes)\n",
 				svc_print_addr(rqstp, buf, sizeof(buf)),
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 64c9755..fd701e6 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -402,6 +402,8 @@ char *		   svc_print_addr(struct svc_rqst *, char *, size_t);
 
 #define	RPC_MAX_ADDRBUFLEN	(63U)
 
+#define DECLARE_RPC_BUF(name)	char name[RPC_MAX_ADDRBUFLEN] __maybe_unused
+
 /*
  * When we want to reduce the size of the reserved space in the response
  * buffer, we need to take into account the size of any checksum data that
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index a290e15..895d365 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -813,7 +813,7 @@ svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
 {
 	va_list args;
 	int 	r;
-	char 	buf[RPC_MAX_ADDRBUFLEN];
+	DECLARE_RPC_BUF(buf);
 
 	if (!net_ratelimit())
 		return 0;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 1d3e5fc..87dc4bc 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -175,7 +175,7 @@ static int svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
 	size_t		base = xdr->page_base;
 	unsigned int	pglen = xdr->page_len;
 	unsigned int	flags = MSG_MORE;
-	char		buf[RPC_MAX_ADDRBUFLEN];
+	DECLARE_RPC_BUF(buf);
 
 	slen = xdr->len;
 
@@ -716,7 +716,7 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
 	struct socket	*newsock;
 	struct svc_sock	*newsvsk;
 	int		err, slen;
-	char		buf[RPC_MAX_ADDRBUFLEN];
+	DECLARE_RPC_BUF(buf);
 
 	dprintk("svc: tcp_accept %p sock %p\n", svsk, sock);
 	if (!sock)
@@ -1206,7 +1206,7 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
 	struct socket	*sock;
 	int		error;
 	int		type;
-	char		buf[RPC_MAX_ADDRBUFLEN];
+	DECLARE_RPC_BUF(buf);
 	struct sockaddr_storage addr;
 	struct sockaddr *newsin = (struct sockaddr *)&addr;
 	int		newlen;

^ permalink raw reply related

* Re: [PATCH] SUNRPC: Mark buffer used for debug printks with __maybe_unused
From: Pavel Emelyanov @ 2008-02-20 16:27 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Joe Perches, J. Bruce Fields, Linux Netdev List
In-Reply-To: <47BC48C6.3050208@trash.net>

Patrick McHardy wrote:
> Joe Perches wrote:
>> On Wed, 2008-02-20 at 07:29 -0800, Joe Perches wrote:
>>   
>>> fs/nfsd/nfsproc.c:              char buf[RPC_MAX_ADDRBUFLEN];
>>> Perhaps there should be a DECLARE_RPC_BUF(buf) macro?
>>> #define DECLARE_RPC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused
>>>     
>> Make that:
>>
>> #define DECLARE_RPC_BUF(var) char var[RPC_MAX_ADDRBUFLEN] __maybe_unuse

OK, I'll send the patch in a moment.

> Alternatively change the dprintk macro to behave similar like

This is too heavy. The problem is that some arguments passed to this
function exist only under appropriate ifdefs, so having a static
inline there will produce a warning :(

> pr_debug() and mark things like svc_print_addr() __pure, which
> has the advantage that is still performs format checking even
> if debugging is disabled.

Taking my above statement into account, this becomes useless, since
svc_print_addr() is used inside those "empty" macros and are complied
out automatically.

> 


^ permalink raw reply

* Re: [RFC PATCH 3/8] [NET]: uninline dev_alloc_skb, de-bloats a lot
From: Patrick McHardy @ 2008-02-20 16:27 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: Ilpo Järvinen, netdev, linux-kernel, David Miller,
	Arnaldo Carvalho de Melo
In-Reply-To: <Pine.LNX.4.64.0802201651580.26109@fbirervta.pbzchgretzou.qr>

Jan Engelhardt wrote:
> On Feb 20 2008 15:47, Ilpo Järvinen wrote:
>> -23668  392 funcs, 104 +, 23772 -, diff: -23668 --- dev_alloc_skb
>>
>> -static inline struct sk_buff *dev_alloc_skb(unsigned int length)
>> -{
>> -	return __dev_alloc_skb(length, GFP_ATOMIC);
>> -}
>> +extern struct sk_buff *dev_alloc_skb(unsigned int length);
> 
> Striking. How can this even happen? A callsite which calls
> 
> 	dev_alloc_skb(n)
> 
> is just equivalent to
> 
> 	__dev_alloc_skb(n, GFP_ATOMIC);
> 
> which means there's like 4 (or 8 if it's long) bytes more on the
> stack. For a worst case, count in another 8 bytes for push and pop or mov on
> the stack. But that still does not add up to 23 kb.


__dev_alloc_skb() is also an inline function which performs
some extra work. Which raises the question - if dev_alloc_skb()
is uninlined, shouldn't __dev_alloc_skb() be uninline as well?

^ permalink raw reply

* Re: [RFC PATCH 3/8] [NET]: uninline dev_alloc_skb, de-bloats a lot
From: Jan Engelhardt @ 2008-02-20 16:19 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: netdev, linux-kernel, David Miller, Arnaldo Carvalho de Melo
In-Reply-To: <1203515238-22848-4-git-send-email-ilpo.jarvinen@helsinki.fi>


On Feb 20 2008 15:47, Ilpo Järvinen wrote:
>
>-23668  392 funcs, 104 +, 23772 -, diff: -23668 --- dev_alloc_skb
>
>-static inline struct sk_buff *dev_alloc_skb(unsigned int length)
>-{
>-	return __dev_alloc_skb(length, GFP_ATOMIC);
>-}
>+extern struct sk_buff *dev_alloc_skb(unsigned int length);

Striking. How can this even happen? A callsite which calls

	dev_alloc_skb(n)

is just equivalent to

	__dev_alloc_skb(n, GFP_ATOMIC);

which means there's like 4 (or 8 if it's long) bytes more on the
stack. For a worst case, count in another 8 bytes for push and pop or mov on
the stack. But that still does not add up to 23 kb.

^ permalink raw reply

* Re: TG3 network data corruption regression 2.6.24/2.6.23.4
From: Tony Battersby @ 2008-02-20 16:13 UTC (permalink / raw)
  To: Matt Carlson
  Cc: Michael Chan, David Miller, herbert, netdev, gregkh, linux-kernel
In-Reply-To: <20080220013824.GA5416@localdomain>

Matt Carlson wrote:
> Hi Tony.  Can you give us the output of :
>
> sudo lspci -vvv -xxxx -s 03:01.0'
>   
03:01.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5701 Gigabit Ethernet (rev 15)
	Subsystem: Compaq Computer Corporation NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T)
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
	Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 64 (16000ns min), Cache Line Size: 64 bytes
	Interrupt: pin A routed to IRQ 17
	Region 0: Memory at df7f0000 (64-bit, non-prefetchable) [size=64K]
	[virtual] Expansion ROM at dfc00000 [disabled] [size=64K]
	Capabilities: [40] PCI-X non-bridge device
		Command: DPERE- ERO- RBC=512 OST=1
		Status: Dev=03:01.1 64bit+ 133MHz+ SCD- USC- DC=simple DMMRBC=512 DMOST=1 DMCRS=8 RSCEM- 266MHz- 533MHz-
	Capabilities: [48] Power Management version 2
		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot+,D3cold+)
		Status: D0 PME-Enable- DSel=0 DScale=1 PME-
	Capabilities: [50] Vital Product Data <?>
	Capabilities: [58] Message Signalled Interrupts: Mask- 64bit+ Queue=0/3 Enable-
		Address: 063000119b608000  Data: 0423
00: e4 14 45 16 06 00 b0 02 15 00 00 02 10 40 00 00
10: 04 00 7f df 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 11 0e 7c 00
30: 00 00 00 00 40 00 00 00 00 00 00 00 0b 01 40 00
40: 07 48 00 00 09 03 03 00 01 50 02 c0 00 20 00 64
50: 03 58 00 00 08 10 21 08 05 00 86 00 00 80 60 9b
60: 11 00 30 06 23 04 00 00 98 02 05 01 0f 00 db 76
70: 8a 10 00 00 c7 00 00 80 50 00 00 00 00 00 00 00
80: 03 58 00 00 00 00 00 00 34 80 13 04 82 10 00 00
90: 09 06 00 01 00 00 00 00 00 00 00 00 c6 01 00 00
a0: 00 00 00 00 fe 02 00 00 00 00 00 00 af 01 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00



> Also, after some digging, I found that the 5701 can run into trouble if
> a 64-bit DMA read terminates early and then completes as a 32-bit transfer.
> The problem is reportedly very rare, but the failure mode looks like a
> match.  Can you apply the following patch and see if it helps your
> performance / corruption problems?
>
>
> diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
> index db606b6..7ad08ce 100644
> --- a/drivers/net/tg3.c
> +++ b/drivers/net/tg3.c
> @@ -11409,6 +11409,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
>  		tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
>  	if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
>  		tp->tg3_flags |= TG3_FLAG_PCI_32BIT;
> +	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)
> +		tp->grc_mode |= GRC_MODE_FORCE_PCI32BIT;
>  
>  	/* Chip-specific fixup from Broadcom driver */
>  	if ((tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) &&
>
>   
Sorry, this didn't help.  I still get data corruption with hardware
checksumming or poor performance with software checksumming.

Tony


^ permalink raw reply

* Re: [PATCH][PPPOL2TP]: Fix SMP oops in pppol2tp driver
From: James Chapman @ 2008-02-20 16:02 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: David Miller, Paul Mackerras, netdev
In-Reply-To: <20080219230640.GA2755@ami.dom.local>

Jarek Poplawski wrote:
> On Mon, Feb 18, 2008 at 10:09:24PM +0000, James Chapman wrote:
> ...
>> Unfortunately the ISP's syslog stops. But I've been able to borrow
>> two Quad Xeon boxes and have reproduced the problem.
>>
>> Here's a new version of the patch. The patch avoids disabling irqs
>> and fixes the sk_dst_get() usage that DaveM mentioned. But even with
>> this patch, lockdep still complains if hundreds of ppp sessions are
>> inserted into a tunnel as rapidly as possible (lockdep trace is below).
>> I can stop these errors by wrapping the call to ppp_input() in
>> pppol2tp_recv_dequeue_skb() with local_irq_save/restore. What is a
>> better fix?
> 
> I send here my proposal: it's intended for testing and to check one of
> possible solutions here. IMHO your lockdep reports show there is no
> use to change anything around sk_dst_lock: it would need the global
> change of this lock to fix this problem. So the fix should be done
> around pch->upl lock and this means changing ppp_generic.

Hmm, I need to study the lockdep report again. It seems I'm misreading 
the lockdep output. :(

> In the patch below I've used trylock in places which seem to allow
> for skipping some things (while config is changed only) or simply
> don't need this lock because there is no ppp struct. This could be
> modified to add some waiting loop if necessary. Another option is to
> change the write side of this lock: it looks like more vulnerable if
> something missed because there are more locks involved, but probably
> should be enough to solve this problem too.
> 
> I think pppol2tp need to be first checked only with hlist_lock bh
> patch, unless there were some lockdep reports on these other locks
> too. (BTW, I added ppp maintainer to CC - I hope we get Paul's opinion
> on this.)

I tried your ppp_generic patch with only the hlist_lock bh patch in 
pppol2tp and it seems to fix the ppp create/delete issue. However, when 
I added much more traffic into the test (flood pings over ppp interfaces 
while repeatedly creating/deleting the L2TP (PPP) sessions) I get a soft 
lockup detected in pppol2tp_xmit() after anything between 1 minute and 
an hour. :( I'm investigating that now.

Thanks for your help!

> (testing patch #1)
> ---
> 
>  drivers/net/ppp_generic.c |   33 +++++++++++++++++++++++----------
>  1 files changed, 23 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
> index 4dc5b4b..5cbc534 100644
> --- a/drivers/net/ppp_generic.c
> +++ b/drivers/net/ppp_generic.c
> @@ -1473,7 +1473,7 @@ void
>  ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
>  {
>  	struct channel *pch = chan->ppp;
> -	int proto;
> +	int proto, locked;
>  
>  	if (!pch || skb->len == 0) {
>  		kfree_skb(skb);
> @@ -1481,8 +1481,13 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
>  	}
>  
>  	proto = PPP_PROTO(skb);
> -	read_lock_bh(&pch->upl);
> -	if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
> +	/*
> +	 * We use trylock to avoid dependency between soft-irq-safe upl lock
> +	 * and soft-irq-unsafe sk_dst_lock.
> +	 */
> +	local_bh_disable();
> +	locked = read_trylock(&pch->upl);
> +	if (!locked || !pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
>  		/* put it on the channel queue */
>  		skb_queue_tail(&pch->file.rq, skb);
>  		/* drop old frames if queue too long */
> @@ -1493,7 +1498,10 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
>  	} else {
>  		ppp_do_recv(pch->ppp, skb, pch);
>  	}
> -	read_unlock_bh(&pch->upl);
> +
> +	if (locked)
> +		read_unlock(&pch->upl);
> +	local_bh_enable();
>  }
>  
>  /* Put a 0-length skb in the receive queue as an error indication */
> @@ -1506,16 +1514,18 @@ ppp_input_error(struct ppp_channel *chan, int code)
>  	if (!pch)
>  		return;
>  
> -	read_lock_bh(&pch->upl);
> -	if (pch->ppp) {
> +	/* a trylock comment in ppp_input() */
> +	local_bh_disable();
> +	if (read_trylock(&pch->upl) && pch->ppp) {
>  		skb = alloc_skb(0, GFP_ATOMIC);
>  		if (skb) {
>  			skb->len = 0;		/* probably unnecessary */
>  			skb->cb[0] = code;
>  			ppp_do_recv(pch->ppp, skb, pch);
>  		}
> +		read_unlock(&pch->upl);
>  	}
> -	read_unlock_bh(&pch->upl);
> +	local_bh_enable();
>  }
>  
>  /*
> @@ -2044,10 +2054,13 @@ int ppp_unit_number(struct ppp_channel *chan)
>  	int unit = -1;
>  
>  	if (pch) {
> -		read_lock_bh(&pch->upl);
> -		if (pch->ppp)
> +		/* a trylock comment in ppp_input() */
> +		local_bh_disable();
> +		if (read_trylock(&pch->upl) && pch->ppp) {
>  			unit = pch->ppp->file.index;
> -		read_unlock_bh(&pch->upl);
> +			read_unlock(&pch->upl);
> +		}
> +		local_bh_enable();
>  	}
>  	return unit;
>  }
> --


-- 
James Chapman
Katalix Systems Ltd
http://www.katalix.com
Catalysts for your Embedded Linux software development


^ permalink raw reply

* Re: [PATCH 04/04] smc91x: add insw/outsw to default config
From: Nicolas Pitre @ 2008-02-20 16:00 UTC (permalink / raw)
  To: Magnus Damm; +Cc: netdev, lethal, akpm
In-Reply-To: <20080220095821.22645.60604.sendpatchset@clockwork.opensource.se>

On Wed, 20 Feb 2008, Magnus Damm wrote:

> This patch makes sure SMC_insw()/SMC_outsw() are defined for the
> default configuration. Without this change BUG()s will be triggered
> when using 16-bit only platform data and the default configuration.
> 
> Signed-off-by: Magnus Damm <damm@igel.co.jp>

You should have introduced this patch as 3/4 instead of 4/4 so to make 
sure the series won't  create a non functional kernel between 3/4 and 
4/4.


Nicolas

^ permalink raw reply

* Re: [PATCH 02/04] smc91x: introduce platform data flags
From: Nicolas Pitre @ 2008-02-20 15:58 UTC (permalink / raw)
  To: Magnus Damm; +Cc: netdev, lethal, akpm
In-Reply-To: <20080220095802.22645.44691.sendpatchset@clockwork.opensource.se>

On Wed, 20 Feb 2008, Magnus Damm wrote:

> This patch introduces struct smc91x_platdata and modifies the driver so
> bus width is checked during run time using SMC_nBIT() instead of
> SMC_CAN_USE_nBIT.
> 
> Signed-off-by: Magnus Damm <damm@igel.co.jp>
> ---

NAK.

The SMC91C111 (for example) is often used on devices which have a CPU 
clock barely higher than the network throughput, hence it is crutial for 
those devices to have the most efficient access possible to the chip or 
performance will suffer.  This is the main reason behind the heavily 
macroized register access so things are always optimized for the data 
bus capabilities at compile time.

This patch introduces a runtimes test on lp->cfg.flags for every 
register access even on those platforms not using the platform data 
based bus configuration at all.

I think you should add a SMC_DYNAMIC_BUS_CONFIG and redefine SMC_nBITS() 
so they dereference cfg.flags only when it is defined.


Nicolas

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox