* Engress path / congestion detection and avoidance
From: Jeba Anandhan @ 2008-02-11 10:38 UTC (permalink / raw)
To: netdev; +Cc: matthew.hattersley
Hi All,
i have few doubts related to congestion and engress path.
1) What happens when congestion hits and how it affects engress path?.
2) How the engress traffic slow down when the congestion hits?
3) what are the variables updated when the congestion hits?
4) is it good to invoke netif_stop_queue when congestion hits?
thanks
Jeba
^ permalink raw reply
* Re: [PATCH][RESEND] drivers/base: export (un)register_memory_notifier
From: Dave Hansen @ 2008-02-11 10:12 UTC (permalink / raw)
To: Jan-Bernd Themann
Cc: Greg KH, Jan-Bernd Themann, Thomas Klein, netdev, linux-kernel,
linux-ppc, Christoph Raisch
In-Reply-To: <200802111049.05478.ossthema@de.ibm.com>
On Mon, 2008-02-11 at 10:49 +0100, Jan-Bernd Themann wrote:
> are you the right person to address this patch to?
You might want to check the top of the file. ;)
> --- a/drivers/base/memory.c
> +++ b/drivers/base/memory.c
> @@ -52,11 +52,13 @@ int register_memory_notifier(struct notifier_block *nb)
> {
> return blocking_notifier_chain_register(&memory_chain, nb);
> }
> +EXPORT_SYMBOL(register_memory_notifier);
>
> void unregister_memory_notifier(struct notifier_block *nb)
> {
> blocking_notifier_chain_unregister(&memory_chain, nb);
> }
> +EXPORT_SYMBOL(unregister_memory_notifier);
Is there a particular reason these can't be GPL?
-- Dave
^ permalink raw reply
* [PATCH][RESEND] drivers/base: export (un)register_memory_notifier
From: Jan-Bernd Themann @ 2008-02-11 9:49 UTC (permalink / raw)
To: Greg KH
Cc: Jan-Bernd Themann, Thomas Klein, netdev, linux-kernel, linux-ppc,
Christoph Raisch
Drivers like eHEA need memory notifiers in order to
update their internal DMA memory map when memory is added
to or removed from the system.
Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com>
---
Hi Greg,
are you the right person to address this patch to?
Regards,
Jan-Bernd
drivers/base/memory.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 7ae413f..1e1bd4c 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -52,11 +52,13 @@ int register_memory_notifier(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&memory_chain, nb);
}
+EXPORT_SYMBOL(register_memory_notifier);
void unregister_memory_notifier(struct notifier_block *nb)
{
blocking_notifier_chain_unregister(&memory_chain, nb);
}
+EXPORT_SYMBOL(unregister_memory_notifier);
/*
* register_memory - Setup a sysfs device for a memory block
--
1.5.2
^ permalink raw reply related
* [PATCH][PPPOL2TP]: Fix SMP oops in pppol2tp driver
From: James Chapman @ 2008-02-11 9:22 UTC (permalink / raw)
To: netdev
Fix locking issues in the pppol2tp driver which can cause a kernel
crash on SMP boxes when hundreds of L2TP sessions are created/deleted
simultaneously (ISP environment). The driver was violating read_lock()
and write_lock() scheduling rules so we now consistently use the _irq
variants of the lock functions.
Signed-off-by: James Chapman <jchapman@katalix.com>
--
This patch has been verified by the ISP that discovered the problem.
If the patch is accepted, it should be pushed to the stable 2.6.23 and
2.6.24 trees.
Index: linux-2.6.24/drivers/net/pppol2tp.c
===================================================================
--- linux-2.6.24.orig/drivers/net/pppol2tp.c
+++ linux-2.6.24/drivers/net/pppol2tp.c
@@ -301,15 +301,16 @@ pppol2tp_session_find(struct pppol2tp_tu
pppol2tp_session_id_hash(tunnel, session_id);
struct pppol2tp_session *session;
struct hlist_node *walk;
+ unsigned long flags;
- read_lock(&tunnel->hlist_lock);
+ read_lock_irqsave(&tunnel->hlist_lock, flags);
hlist_for_each_entry(session, walk, session_list, hlist) {
if (session->tunnel_addr.s_session == session_id) {
- read_unlock(&tunnel->hlist_lock);
+ read_unlock_irqrestore(&tunnel->hlist_lock, flags);
return session;
}
}
- read_unlock(&tunnel->hlist_lock);
+ read_unlock_irqrestore(&tunnel->hlist_lock, flags);
return NULL;
}
@@ -319,15 +320,16 @@ pppol2tp_session_find(struct pppol2tp_tu
static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
{
struct pppol2tp_tunnel *tunnel = NULL;
+ unsigned long flags;
- read_lock(&pppol2tp_tunnel_list_lock);
+ read_lock_irqsave(&pppol2tp_tunnel_list_lock, flags);
list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
if (tunnel->stats.tunnel_id == tunnel_id) {
- read_unlock(&pppol2tp_tunnel_list_lock);
+ read_unlock_irqrestore(&pppol2tp_tunnel_list_lock, flags);
return tunnel;
}
}
- read_unlock(&pppol2tp_tunnel_list_lock);
+ read_unlock_irqrestore(&pppol2tp_tunnel_list_lock, flags);
return NULL;
}
@@ -1099,6 +1101,7 @@ static void pppol2tp_tunnel_closeall(str
struct hlist_node *tmp;
struct pppol2tp_session *session;
struct sock *sk;
+ unsigned long flags;
if (tunnel == NULL)
BUG();
@@ -1106,7 +1109,7 @@ static void pppol2tp_tunnel_closeall(str
PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
"%s: closing all sessions...\n", tunnel->name);
- write_lock(&tunnel->hlist_lock);
+ write_lock_irqsave(&tunnel->hlist_lock, flags);
for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
again:
hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
@@ -1126,7 +1129,7 @@ again:
* disappear as we're jumping between locks.
*/
sock_hold(sk);
- write_unlock(&tunnel->hlist_lock);
+ write_unlock_irqrestore(&tunnel->hlist_lock, flags);
lock_sock(sk);
if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
@@ -1148,11 +1151,11 @@ again:
* list so we are guaranteed to make forward
* progress.
*/
- write_lock(&tunnel->hlist_lock);
+ write_lock_irqsave(&tunnel->hlist_lock, flags);
goto again;
}
}
- write_unlock(&tunnel->hlist_lock);
+ write_unlock_irqrestore(&tunnel->hlist_lock, flags);
}
/* Really kill the tunnel.
@@ -1160,10 +1163,12 @@ again:
*/
static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
{
+ unsigned long flags;
+
/* Remove from socket list */
- write_lock(&pppol2tp_tunnel_list_lock);
+ write_lock_irqsave(&pppol2tp_tunnel_list_lock, flags);
list_del_init(&tunnel->list);
- write_unlock(&pppol2tp_tunnel_list_lock);
+ write_unlock_irqrestore(&pppol2tp_tunnel_list_lock, flags);
atomic_dec(&pppol2tp_tunnel_count);
kfree(tunnel);
@@ -1212,6 +1217,7 @@ end:
static void pppol2tp_session_destruct(struct sock *sk)
{
struct pppol2tp_session *session = NULL;
+ unsigned long flags;
if (sk->sk_user_data != NULL) {
struct pppol2tp_tunnel *tunnel;
@@ -1239,9 +1245,9 @@ static void pppol2tp_session_destruct(st
/* Delete the session socket from the
* hash
*/
- write_lock(&tunnel->hlist_lock);
+ write_lock_irqsave(&tunnel->hlist_lock, flags);
hlist_del_init(&session->hlist);
- write_unlock(&tunnel->hlist_lock);
+ write_unlock_irqrestore(&tunnel->hlist_lock, flags);
atomic_dec(&pppol2tp_session_count);
}
@@ -1312,6 +1318,7 @@ static struct sock *pppol2tp_prepare_tun
struct sock *sk;
struct pppol2tp_tunnel *tunnel;
struct sock *ret = NULL;
+ unsigned long flags;
/* Get the tunnel UDP socket from the fd, which was opened by
* the userspace L2TP daemon.
@@ -1386,9 +1393,9 @@ static struct sock *pppol2tp_prepare_tun
/* Add tunnel to our list */
INIT_LIST_HEAD(&tunnel->list);
- write_lock(&pppol2tp_tunnel_list_lock);
+ write_lock_irqsave(&pppol2tp_tunnel_list_lock, flags);
list_add(&tunnel->list, &pppol2tp_tunnel_list);
- write_unlock(&pppol2tp_tunnel_list_lock);
+ write_unlock_irqrestore(&pppol2tp_tunnel_list_lock, flags);
atomic_inc(&pppol2tp_tunnel_count);
/* Bump the reference count. The tunnel context is deleted
@@ -1462,6 +1469,7 @@ static int pppol2tp_connect(struct socke
struct pppol2tp_tunnel *tunnel;
struct dst_entry *dst;
int error = 0;
+ unsigned long irqflags;
lock_sock(sk);
@@ -1593,11 +1601,11 @@ static int pppol2tp_connect(struct socke
sk->sk_user_data = session;
/* Add session to the tunnel's hash list */
- write_lock(&tunnel->hlist_lock);
+ write_lock_irqsave(&tunnel->hlist_lock, irqflags);
hlist_add_head(&session->hlist,
pppol2tp_session_id_hash(tunnel,
session->tunnel_addr.s_session));
- write_unlock(&tunnel->hlist_lock);
+ write_unlock_irqrestore(&tunnel->hlist_lock, irqflags);
atomic_inc(&pppol2tp_session_count);
@@ -2198,8 +2206,9 @@ static struct pppol2tp_session *next_ses
int found = 0;
int next = 0;
int i;
+ unsigned long flags;
- read_lock(&tunnel->hlist_lock);
+ read_lock_irqsave(&tunnel->hlist_lock, flags);
for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) {
hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) {
if (curr == NULL) {
@@ -2217,7 +2226,7 @@ static struct pppol2tp_session *next_ses
}
}
out:
- read_unlock(&tunnel->hlist_lock);
+ read_unlock_irqrestore(&tunnel->hlist_lock, flags);
if (!found)
session = NULL;
@@ -2227,14 +2236,15 @@ out:
static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
{
struct pppol2tp_tunnel *tunnel = NULL;
+ unsigned long flags;
- read_lock(&pppol2tp_tunnel_list_lock);
+ read_lock_irqsave(&pppol2tp_tunnel_list_lock, flags);
if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
goto out;
}
tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
out:
- read_unlock(&pppol2tp_tunnel_list_lock);
+ read_unlock_irqrestore(&pppol2tp_tunnel_list_lock, flags);
return tunnel;
}
^ permalink raw reply
* [PATCH] [RESENDING] netconsole: register cmdline netconsole configs to configfs
From: Joonwoo Park @ 2008-02-11 9:08 UTC (permalink / raw)
To: akpm; +Cc: Joonwoo Park, linux-kernel, netdev, satyam, mpm
In-Reply-To: <12027209163465-git-send-email-joonwpark81@gmail.com>
This patch intorduces cmdline netconsole configs to register to configfs
with dynamic netconsole. Satyam Sharma who designed shiny dynamic
reconfiguration for netconsole, mentioned about this issue already.
(http://lkml.org/lkml/2007/7/29/360)
But I think, without separately managing of two kind of netconsole target
objects, it's possible by using config_group instead of
config_item in the netconsole_target and default_groups feature of configfs.
Patch was tested with configuration creation/destruction by kernel and
module.
And it makes possible to enable/disable, modify and review netconsole
target configs from cmdline.
Signed-off-by: Joonwoo Park <joonwpark81@gmail.com>
---
drivers/net/netconsole.c | 91 ++++++++++++++++++++++++++++++++++++----------
1 files changed, 72 insertions(+), 19 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 31e047d..63aabbb 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -93,7 +93,7 @@ static DEFINE_SPINLOCK(target_list_lock);
struct netconsole_target {
struct list_head list;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
- struct config_item item;
+ struct config_group group;
#endif
int enabled;
struct netpoll np;
@@ -103,16 +103,49 @@ struct netconsole_target {
static struct configfs_subsystem netconsole_subsys;
-static int __init dynamic_netconsole_init(void)
+static void netconsole_target_put(struct netconsole_target *nt);
+static struct config_item_type netconsole_target_type;
+
+static int __init dynamic_netconsole_init(int defaults)
{
+ int err;
+ unsigned long flags;
config_group_init(&netconsole_subsys.su_group);
+
+ if (defaults > 0) {
+ struct list_head *pos;
+ struct config_group **groups;
+ int i = 0;
+
+ groups = kcalloc(defaults, sizeof(struct config_group *),
+ GFP_KERNEL);
+ if (!groups)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&target_list_lock, flags);
+ list_for_each(pos, &target_list) {
+ struct netconsole_target *nt;
+ nt = list_entry(pos, struct netconsole_target, list);
+ groups[i] = &nt->group;
+ i++;
+ }
+ spin_unlock_irqrestore(&target_list_lock, flags);
+ netconsole_subsys.su_group.default_groups = groups;
+ }
+
mutex_init(&netconsole_subsys.su_mutex);
- return configfs_register_subsystem(&netconsole_subsys);
+
+ err = configfs_register_subsystem(&netconsole_subsys);
+ if (err)
+ kfree(netconsole_subsys.su_group.default_groups);
+
+ return err;
}
static void __exit dynamic_netconsole_exit(void)
{
configfs_unregister_subsystem(&netconsole_subsys);
+ kfree(netconsole_subsys.su_group.default_groups);
}
/*
@@ -122,14 +155,23 @@ static void __exit dynamic_netconsole_exit(void)
*/
static void netconsole_target_get(struct netconsole_target *nt)
{
- if (config_item_name(&nt->item))
- config_item_get(&nt->item);
+ if (config_item_name(&nt->group.cg_item))
+ config_item_get(&nt->group.cg_item);
}
static void netconsole_target_put(struct netconsole_target *nt)
{
- if (config_item_name(&nt->item))
- config_item_put(&nt->item);
+ if (config_item_name(&nt->group.cg_item))
+ config_item_put(&nt->group.cg_item);
+}
+
+static void dynamic_netconsole_init_type_name(struct netconsole_target *nt,
+ int index)
+{
+ char name[16];
+ snprintf(name, sizeof(name), "netcon%d", index);
+ config_item_init_type_name(&nt->group.cg_item, name,
+ &netconsole_target_type);
}
#else /* !CONFIG_NETCONSOLE_DYNAMIC */
@@ -155,6 +197,11 @@ static void netconsole_target_put(struct netconsole_target *nt)
{
}
+static void dynamic_netconsole_init_type_name(struct netconsole_target *nt,
+ int index)
+{
+}
+
#endif /* CONFIG_NETCONSOLE_DYNAMIC */
/* Allocate new target (from boot/module param) and setup netpoll for it */
@@ -236,8 +283,8 @@ struct netconsole_target_attr {
static struct netconsole_target *to_target(struct config_item *item)
{
return item ?
- container_of(item, struct netconsole_target, item) :
- NULL;
+ container_of(to_config_group(item), struct netconsole_target,
+ group) : NULL;
}
/*
@@ -370,7 +417,7 @@ static ssize_t store_dev_name(struct netconsole_target *nt,
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
"disable to update parameters\n",
- config_item_name(&nt->item));
+ config_item_name(&nt->group.cg_item));
return -EINVAL;
}
@@ -394,7 +441,7 @@ static ssize_t store_local_port(struct netconsole_target *nt,
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
"disable to update parameters\n",
- config_item_name(&nt->item));
+ config_item_name(&nt->group.cg_item));
return -EINVAL;
}
@@ -417,7 +464,7 @@ static ssize_t store_remote_port(struct netconsole_target *nt,
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
"disable to update parameters\n",
- config_item_name(&nt->item));
+ config_item_name(&nt->group.cg_item));
return -EINVAL;
}
@@ -437,7 +484,7 @@ static ssize_t store_local_ip(struct netconsole_target *nt,
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
"disable to update parameters\n",
- config_item_name(&nt->item));
+ config_item_name(&nt->group.cg_item));
return -EINVAL;
}
@@ -453,7 +500,7 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
"disable to update parameters\n",
- config_item_name(&nt->item));
+ config_item_name(&nt->group.cg_item));
return -EINVAL;
}
@@ -473,7 +520,7 @@ static ssize_t store_remote_mac(struct netconsole_target *nt,
if (nt->enabled) {
printk(KERN_ERR "netconsole: target (%s) is enabled, "
"disable to update parameters\n",
- config_item_name(&nt->item));
+ config_item_name(&nt->group.cg_item));
return -EINVAL;
}
@@ -608,14 +655,15 @@ static struct config_item *make_netconsole_target(struct config_group *group,
memset(nt->np.remote_mac, 0xff, ETH_ALEN);
/* Initialize the config_item member */
- config_item_init_type_name(&nt->item, name, &netconsole_target_type);
+ config_item_init_type_name(&nt->group.cg_item, name,
+ &netconsole_target_type);
/* Adding, but it is disabled */
spin_lock_irqsave(&target_list_lock, flags);
list_add(&nt->list, &target_list);
spin_unlock_irqrestore(&target_list_lock, flags);
- return &nt->item;
+ return &nt->group.cg_item;
}
static void drop_netconsole_target(struct config_group *group,
@@ -635,7 +683,7 @@ static void drop_netconsole_target(struct config_group *group,
if (nt->enabled)
netpoll_cleanup(&nt->np);
- config_item_put(&nt->item);
+ config_item_put(&nt->group.cg_item);
}
static struct configfs_group_operations netconsole_subsys_group_ops = {
@@ -741,6 +789,7 @@ static int __init init_netconsole(void)
unsigned long flags;
char *target_config;
char *input = config;
+ int i = 0;
if (strnlen(input, MAX_PARAM_LENGTH)) {
while ((target_config = strsep(&input, ";"))) {
@@ -749,9 +798,13 @@ static int __init init_netconsole(void)
err = PTR_ERR(nt);
goto fail;
}
+
+ dynamic_netconsole_init_type_name(nt, i);
+
spin_lock_irqsave(&target_list_lock, flags);
list_add(&nt->list, &target_list);
spin_unlock_irqrestore(&target_list_lock, flags);
+ i++;
}
}
@@ -759,7 +812,7 @@ static int __init init_netconsole(void)
if (err)
goto fail;
- err = dynamic_netconsole_init();
+ err = dynamic_netconsole_init(i);
if (err)
goto undonotifier;
--
1.5.3.rc5
^ permalink raw reply related
* Re: [PATCH][RFC] race in generic address resolution
From: Frank Blaschka @ 2008-02-11 9:01 UTC (permalink / raw)
To: David Miller, netdev
In-Reply-To: <20080205.205154.153345843.davem@davemloft.net>
David Miller schrieb:
> From: Blaschka <frank.blaschka@de.ibm.com>
> Date: Mon, 4 Feb 2008 15:27:17 +0100
>
>> I'm running a SMP maschine (2 CPUs) configured as a router. During heavy
>> traffic kernel dies with following message:
>>
>> <2>kernel BUG at /home/autobuild/BUILD/linux-2.6.23-20080125/net/core/skbuff.c:648!
> ...
>> Following patch fixes the problem but I do not know if it is a good sollution.
>>
>> From: Frank Blaschka <frank.blaschka@de.ibm.com>
>>
>> neigh_update sends skb from neigh->arp_queue while
>> neigh_timer_handler has increased skbs refcount and calls
>> solicit with the skb. Do not send neighbour skbs
>> marked for solicit (skb_shared).
>>
>> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
>
> Thanks for finding this bug.
>
> I'm fine with your approach as a temporary fix, but there is a slight
> problem with your patch. If the skb is shared we have to free it if
> we don't pass it on to ->output(), otherwise this creates a leak.
>
> In the longer term, this is an unfortunate limitation. The
> ->solicit() code just wants to look at a few header fields to
> determine how to construct the solicitation request.
>
> What's funny is that we added these skb_get() calls for
> the solications exactly to deal with this race condition.
>
> I considered various ways to fix this. The simplest is probably just
> to skb_copy() in the ->solicit() case. Solicitation is a rare event
> so it's not big deal to copy the packet until the neighbour is
> resolved.
>
> The other option is holding the write lock on neigh->lock during the
> ->solicit() call. I looked at all of the ndisc_ops implementations
> and this seems workable. The only case that needs special care is the
> IPV4 ARP implementation of arp_solicit(). It wants to take
> neigh->lock as a reader to protect the header entry in neigh->ha
> during the emission of the soliciation. We can simply remove the read
> lock calls to take care of that since holding the lock as a writer at
> the caller providers a superset of the protection afforded by the
> existing read locking.
>
> The rest of the ->solicit() implementations don't care whether
> the neigh is locked or not.
>
> Can you see if this version of the patch fixes your problem?
>
> Thanks!
>
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index a16cf1e..7bb6a9a 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -834,18 +834,12 @@ static void neigh_timer_handler(unsigned long arg)
> }
> if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
> struct sk_buff *skb = skb_peek(&neigh->arp_queue);
> - /* keep skb alive even if arp_queue overflows */
> - if (skb)
> - skb_get(skb);
> - write_unlock(&neigh->lock);
> +
> neigh->ops->solicit(neigh, skb);
> atomic_inc(&neigh->probes);
> - if (skb)
> - kfree_skb(skb);
> - } else {
> -out:
> - write_unlock(&neigh->lock);
> }
> +out:
> + write_unlock(&neigh->lock);
>
> if (notify)
> neigh_update_notify(neigh);
> diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
> index 8e17f65..c663fa5 100644
> --- a/net/ipv4/arp.c
> +++ b/net/ipv4/arp.c
> @@ -368,7 +368,6 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
> if (!(neigh->nud_state&NUD_VALID))
> printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n");
> dst_ha = neigh->ha;
> - read_lock_bh(&neigh->lock);
> } else if ((probes -= neigh->parms->app_probes) < 0) {
> #ifdef CONFIG_ARPD
> neigh_app_ns(neigh);
> @@ -378,8 +377,6 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
>
> arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
> dst_ha, dev->dev_addr, NULL);
> - if (dst_ha)
> - read_unlock_bh(&neigh->lock);
> }
>
> static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
> --
> 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
>
Hi Dave,
we run your patch during the weekend on single CPU and SMP machines. We do not
see any problems. Thanks for providing the fix.
Best regards,
Frank
^ permalink raw reply
* [BUG][AX25] mkiss and ax25_route lockdep warning
From: Jann Traschewski @ 2008-02-11 8:56 UTC (permalink / raw)
To: netdev
Hello,
After using "Lock debugging: prove locking correctness" with the Kernel I
got this warning:
=================================
[ INFO: inconsistent lock state ]
2.6.24-dg8ngn-p02 #1
---------------------------------
inconsistent {softirq-on-W} -> {in-softirq-R} usage.
linuxnet/3046 [HC0[0]:SC1[2]:HE1:SE0] takes:
(ax25_route_lock){--.+}, at: [<f8a0cfb7>] ax25_get_route+0x18/0xb7 [ax25]
{softirq-on-W} state was registered at:
[<c013a340>] __lock_acquire+0x464/0xb7b
[<c01398d8>] mark_held_locks+0x39/0x53
[<c0124d35>] local_bh_enable_ip+0xcd/0xd5
[<c0139aaf>] trace_hardirqs_on+0x11a/0x13d
[<c013ae58>] lock_acquire+0x5f/0x77
[<f8a0d381>] ax25_rt_ioctl+0x66/0x325 [ax25]
[<c0299ce7>] _write_lock+0x29/0x34
[<f8a0d381>] ax25_rt_ioctl+0x66/0x325 [ax25]
[<f8a0d381>] ax25_rt_ioctl+0x66/0x325 [ax25]
[<f8a0f699>] ax25_ioctl+0x1b6/0x5b8 [ax25]
[<c0161280>] fd_install+0x1e/0x46
[<c0299c7a>] _spin_lock+0x29/0x34
[<c022e75d>] sock_ioctl+0x1bb/0x1e0
[<c022e5a2>] sock_ioctl+0x0/0x1e0
[<c016c76f>] do_ioctl+0x1f/0x62
[<c016c9d2>] vfs_ioctl+0x220/0x232
[<c0139aaf>] trace_hardirqs_on+0x11a/0x13d
[<c016ca17>] sys_ioctl+0x33/0x4c
[<c0103ea2>] syscall_call+0x7/0xb
[<ffffffff>] 0xffffffff
irq event stamp: 120000
hardirqs last enabled at (120000): [<c0124d35>]
local_bh_enable_ip+0xcd/0xd5
hardirqs last disabled at (119999): [<c0124cc3>]
local_bh_enable_ip+0x5b/0xd5
softirqs last enabled at (119892): [<f89fd53d>]
mkiss_receive_buf+0x2a5/0x394 [mkiss]
softirqs last disabled at (119893): [<c01249f0>] do_softirq+0x37/0x4d
other info that might help us debug this:
5 locks held by linuxnet/3046:
#0: (&tty->atomic_write_lock){--..}, at: [<c01ded5e>]
tty_write_lock+0x11/0x37
#1: (rcu_read_lock){..--}, at: [<c023a8d2>] net_rx_action+0x4e/0x1c4
#2: (rcu_read_lock){..--}, at: [<c0238579>] netif_receive_skb+0xe6/0x3d6
#3: (rcu_read_lock){..--}, at: [<c025549d>]
ip_local_deliver_finish+0x2d/0x1f7
#4: (slock-AF_INET){-+..}, at: [<c0274e43>] icmp_send+0x10e/0x37a
stack backtrace:
Pid: 3046, comm: linuxnet Not tainted 2.6.24-dg8ngn-p02 #1
[<c0138e13>] print_usage_bug+0x138/0x142
[<c013961f>] mark_lock+0x1ca/0x44a
[<c013a2d9>] __lock_acquire+0x3fd/0xb7b
[<c01398d8>] mark_held_locks+0x39/0x53
[<c0124d35>] local_bh_enable_ip+0xcd/0xd5
[<c013ae58>] lock_acquire+0x5f/0x77
[<f8a0cfb7>] ax25_get_route+0x18/0xb7 [ax25]
[<c0299dc7>] _read_lock+0x29/0x34
[<f8a0cfb7>] ax25_get_route+0x18/0xb7 [ax25]
[<f8a0cfb7>] ax25_get_route+0x18/0xb7 [ax25]
[<f89fda29>] ax_header+0x0/0x1a [mkiss]
[<f8a0c3f6>] ax25_rebuild_header+0x30/0x202 [ax25]
[<f89fda29>] ax_header+0x0/0x1a [mkiss]
[<c023f90c>] neigh_compat_output+0x7b/0x97
[<c0258bd6>] ip_finish_output+0x1da/0x204
[<c0259a26>] ip_output+0x74/0x89
[<c0257831>] ip_push_pending_frames+0x2d8/0x33a
[<c025742c>] dst_output+0x0/0x7
[<c0275039>] icmp_send+0x304/0x37a
[<c013a353>] __lock_acquire+0x477/0xb7b
[<c0270c05>] __udp4_lib_lookup+0xec/0xf6
[<c0271a48>] __udp4_lib_rcv+0x586/0x771
[<c02555ae>] ip_local_deliver_finish+0x13e/0x1f7
[<c025549d>] ip_local_deliver_finish+0x2d/0x1f7
[<c0255451>] ip_rcv_finish+0x2c1/0x2e0
[<c025591c>] ip_rcv+0x1f0/0x22b
[<c0255190>] ip_rcv_finish+0x0/0x2e0
[<c0238808>] netif_receive_skb+0x375/0x3d6
[<c0238579>] netif_receive_skb+0xe6/0x3d6
[<c023adc4>] process_backlog+0x6c/0xcd
[<c023a940>] net_rx_action+0xbc/0x1c4
[<c023a8d2>] net_rx_action+0x4e/0x1c4
[<c0124944>] __do_softirq+0x69/0xde
[<f89fd53d>] mkiss_receive_buf+0x2a5/0x394 [mkiss]
[<c01249f0>] do_softirq+0x37/0x4d
[<c0124d15>] local_bh_enable_ip+0xad/0xd5
[<f89fd53d>] mkiss_receive_buf+0x2a5/0x394 [mkiss]
[<c029a042>] _spin_unlock_irqrestore+0x34/0x39
[<c01e3233>] pty_write+0x2f/0x39
[<c01e1233>] write_chan+0x22d/0x2a1
[<c01191e7>] default_wake_function+0x0/0x8
[<c01def37>] tty_write+0x14d/0x1c2
[<c01e1006>] write_chan+0x0/0x2a1
[<c01dedea>] tty_write+0x0/0x1c2
[<c0162f28>] vfs_write+0x8a/0x10c
[<c01634a4>] sys_write+0x41/0x67
[<c0103ea2>] syscall_call+0x7/0xb
=======================
--
Jann Traschewski, Drosselstr.1, D-90513 Zirndorf, Germany
Tel.: +49-911-696971, Mobile: +49-170-1045937, EMail: jann@gmx.de
Ham: DG8NGN / DB0VOX, http://www.qsl.net/db0fhn, ICQ UIN: 4130182
^ permalink raw reply
* [PATCH] [IPV4]: Remove warning in node_set_parent.
From: Denis V. Lunev @ 2008-02-11 8:47 UTC (permalink / raw)
To: davem; +Cc: netdev, devel, shemminger, Denis V. Lunev
net/ipv4/fib_trie.c: In function 'node_set_parent':
net/ipv4/fib_trie.c:184: warning: assignment makes integer from pointer
without a cast
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
net/ipv4/fib_trie.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index f5fba3f..1753cd4 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -177,10 +177,11 @@ static inline struct tnode *node_parent_rcu(struct node *node)
return rcu_dereference(ret);
}
-static inline void node_set_parent(struct node *node, struct tnode *ptr)
+static inline void node_set_parent(struct node *node, struct tnode *__ptr)
{
- rcu_assign_pointer(node->parent,
- (unsigned long)ptr | NODE_TYPE(node));
+ struct node *ptr;
+ ptr = (struct node *)((unsigned long)__ptr | NODE_TYPE(node));
+ rcu_assign_pointer(node->parent, ptr);
}
static inline struct node *tnode_get_child(struct tnode *tn, unsigned int i)
--
1.5.3.rc5
^ permalink raw reply related
* Re: [patch 1/7] typhoon section fix
From: Jan Beulich @ 2008-02-11 8:22 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: davem, jeff, Andrew Morton, David Dillow, netdev
In-Reply-To: <20080208190340.GA31072@uranus.ravnborg.org>
>So do we have other options that to drop the constification and thus
>dropping the __devinitconst and the other __*const annotations - I think not :-(
As I had said already in another reply - I think the most reasonable thing
to do is to fold section name attribute *and* const into __*initconst
(while defining __*initconst to __*initdata on those targets not allowing
relocations in read-only sections, which should be done by a promptless
config option to avoid enumerating all the targets each time such a
conditional is needed somewhere). While that doesn't allow the 'const'
compile time checking on those problem targets, it is consistent for all
targets and provides the intended DEBUG_RODATA benefit where
possible. Additionally, the const compile time checking will then be more
tight on the presumable more frequently tested x86 targets, so the
chances of bad constructs slipping in should be reduced.
Jan
^ permalink raw reply
* Re: Netfilter fixes to 2.6.24-git
From: Jarek Poplawski @ 2008-02-11 8:17 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netdev
In-Reply-To: <47AFF28A.9090808@trash.net>
On 11-02-2008 08:00, Patrick McHardy wrote:
...
> Indeed, I'm currently ill and not really up for much working,
> but this will hopefully get better soon.
Wish you well, Patrick!
I hope it's about some WARN_ON not BUG_ON?
Anyway, drop these last patches and get back to stable!
Regards,
Jarek P.
^ permalink raw reply
* Re: [patch 1/2] qeth: new qeth device driver
From: Frank Blaschka @ 2008-02-11 7:55 UTC (permalink / raw)
To: paulmck; +Cc: netdev
In-Reply-To: <20080208155416.GB12085@linux.vnet.ibm.com>
Paul E. McKenney schrieb:
> On Fri, Feb 08, 2008 at 03:10:00PM +0100, Frank.Blaschka@de.ibm.com wrote:
>> From: Frank Blaschka <frank.blaschka@de.ibm.com>
>>
>> List of major changes and improvements:
>> no manipulation of the global ARP constructor
>> clean code split into core, layer 2 and layer 3 functionality
>> better exploitation of the ethtool interface
>> better representation of the various hardware capabilities
>> fix packet socket support (tcpdump), no fake_ll required
>> osasnmpd notification via udev events
>> coding style and beautification
>
> One question below...
>
>> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
>> ---
>
> [ . . . ]
>
>> +static void qeth_l3_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
>> +{
>> + struct net_device *vlandev;
>> + struct qeth_card *card = (struct qeth_card *) dev->priv;
>> + struct in_device *in_dev;
>> +
>> + if (card->info.type == QETH_CARD_TYPE_IQD)
>> + return;
>> +
>> + vlandev = vlan_group_get_device(card->vlangrp, vid);
>> + vlandev->neigh_setup = qeth_l3_neigh_setup;
>> +
>> + in_dev = __in_dev_get_rcu(vlandev);
>
> Is this really in an RCU read-side critical section? Or is this just
> using common code?
>
> Thanx, Paul
> --
> 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
>
Hi Paul,
thanks for pointing at this. Using __in_dev_get_rcu without the rcu lock
is probably a bug at this place (right?). Using in_dev_get/in_dev_put
would be more appropriate. Same for qeth_l3_free_vlan_addresses4(), here
we take the rcu read lock, but in_dev_get/in_dev_put would be the better
choice. What do you think?
Best regards,
Frank
^ permalink raw reply
* Re: Netfilter fixes to 2.6.24-git
From: Patrick McHardy @ 2008-02-11 7:00 UTC (permalink / raw)
To: David Miller; +Cc: jengelh, netdev, linux-kernel, netfilter-devel, torvalds
In-Reply-To: <20080210.212754.55064006.davem@davemloft.net>
David Miller wrote:
> From: Jan Engelhardt <jengelh@computergmbh.de>
> Date: Sun, 10 Feb 2008 22:02:35 +0100 (CET)
>
>> I have been unable to reach the netfilter and net maintainers the past
>> week regarding inclusion of patches, but most importantly a group of
>> fixes at [0]-[3]. I am kind of at a loss here but to turn up the volume
>> and write to more people on how to proceed.
>
> You just need to be patient and wait for Patrick to get to your
> patches, it's as simple as that :-)
>
> Patrick is normally very responsive, so whatever it is it has to be a
> temporary issue.
Indeed, I'm currently ill and not really up for much working,
but this will hopefully get better soon.
^ permalink raw reply
* Re: Netfilter fixes to 2.6.24-git
From: David Miller @ 2008-02-11 5:27 UTC (permalink / raw)
To: jengelh; +Cc: netdev, linux-kernel, netfilter-devel, kaber, torvalds
In-Reply-To: <Pine.LNX.4.64.0802102146590.7915@fbirervta.pbzchgretzou.qr>
From: Jan Engelhardt <jengelh@computergmbh.de>
Date: Sun, 10 Feb 2008 22:02:35 +0100 (CET)
> I have been unable to reach the netfilter and net maintainers the past
> week regarding inclusion of patches, but most importantly a group of
> fixes at [0]-[3]. I am kind of at a loss here but to turn up the volume
> and write to more people on how to proceed.
You just need to be patient and wait for Patrick to get to your
patches, it's as simple as that :-)
Patrick is normally very responsive, so whatever it is it has to be a
temporary issue.
Because of LCA08 etc. I myself wasn't even able to get any networking
bug fix submissions into 2.6.24.1
Big deal, we'll just get it into the next 2.6.24.x release.
Thanks for your patience.
^ permalink raw reply
* [2.6.25-rc1] Locks in udp_recvmsg()?
From: Tetsuo Handa @ 2008-02-11 2:20 UTC (permalink / raw)
To: netdev
Hello.
I found that udp_recvmsg() in net/ipv4/udp.c for 2.6.25-rc1 calls
lock_sock() only when it releases the datagram (i.e. out_free: and csum_copy_err:).
Is it correct to call __skb_recv_datagram() without calling lock_sock()
when it acquires the datagram (i.e. try_again:)?
Regards.
^ permalink raw reply
* Re: Pull request for 'r6040' branch
From: Florian Fainelli @ 2008-02-10 21:32 UTC (permalink / raw)
To: Francois Romieu; +Cc: jeff, netdev, Sten Wang, Andrew Morton
In-Reply-To: <20080205223452.GA8361@electric-eye.fr.zoreil.com>
Hi Francois, Jeff,
Le mardi 5 février 2008, Francois Romieu a écrit :
> Please pull from branch 'r6040' in repository
>
> git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev-2.6.git r6040
>
> to get the changes below.
>
> I have simply rebased the r6040 branch from december on top of
> Linus's latest head and given each patch a compile test.
> The content is identical to Florian's initial work (minus the
> removal of the unused TIMER_WUT and a duplicate update of an
> error counter).
Thank you very much Francois. Jeff, any news on this ?
--
Cordialement, Florian Fainelli
------------------------------
^ permalink raw reply
* HTB(?) softlockup, vanilla 2.6.24
From: Denys Fedoryshchenko @ 2008-02-10 21:29 UTC (permalink / raw)
To: netdev
It is very difficult to reproduce, happened after running about 1month. No
changes done in classes at that time
Feb 10 15:53:22 SHAPER [ 8271.778915] BUG: NMI Watchdog detected LOCKUP
Feb 10 15:53:22 SHAPER on CPU1, eip c01f0e5d, registers:
Feb 10 15:53:22 SHAPER [ 8271.778952] Modules linked in:
Feb 10 15:53:22 SHAPER netconsole
Feb 10 15:53:22 SHAPER configfs
Feb 10 15:53:22 SHAPER softdog
Feb 10 15:53:22 SHAPER nf_nat_pptp
Feb 10 15:53:22 SHAPER nf_conntrack_pptp
Feb 10 15:53:22 SHAPER nf_conntrack_proto_gre
Feb 10 15:53:22 SHAPER nf_nat_proto_gre
Feb 10 15:53:22 SHAPER xt_tcpudp
Feb 10 15:53:22 SHAPER ipt_TTL
Feb 10 15:53:22 SHAPER ipt_ttl
Feb 10 15:53:22 SHAPER xt_NOTRACK
Feb 10 15:53:22 SHAPER iptable_raw
Feb 10 15:53:22 SHAPER iptable_mangle
Feb 10 15:53:22 SHAPER ifb
Feb 10 15:53:22 SHAPER e1000e
Feb 10 15:53:22 SHAPER em_nbyte
Feb 10 15:53:22 SHAPER cls_tcindex
Feb 10 15:53:22 SHAPER act_gact
Feb 10 15:53:22 SHAPER cls_rsvp
Feb 10 15:53:22 SHAPER sch_htb
Feb 10 15:53:22 SHAPER cls_fw
Feb 10 15:53:22 SHAPER act_mirred
Feb 10 15:53:22 SHAPER em_u32
Feb 10 15:53:22 SHAPER sch_red
Feb 10 15:53:22 SHAPER sch_sfq
Feb 10 15:53:22 SHAPER sch_tbf
Feb 10 15:53:22 SHAPER sch_teql
Feb 10 15:53:22 SHAPER cls_basic
Feb 10 15:53:22 SHAPER act_police
Feb 10 15:53:22 SHAPER sch_gred
Feb 10 15:53:22 SHAPER act_pedit
Feb 10 15:53:22 SHAPER sch_hfsc
Feb 10 15:53:22 SHAPER cls_rsvp6
Feb 10 15:53:22 SHAPER sch_ingress
Feb 10 15:53:22 SHAPER em_meta
Feb 10 15:53:22 SHAPER em_text
Feb 10 15:53:22 SHAPER act_ipt
Feb 10 15:53:22 SHAPER sch_dsmark
Feb 10 15:53:22 SHAPER sch_prio
Feb 10 15:53:22 SHAPER sch_netem
Feb 10 15:53:22 SHAPER act_simple
Feb 10 15:53:22 SHAPER cls_u32
Feb 10 15:53:22 SHAPER em_cmp
Feb 10 15:53:22 SHAPER sch_cbq
Feb 10 15:53:22 SHAPER cls_route
Feb 10 15:53:22 SHAPER xt_TCPMSS
Feb 10 15:53:22 SHAPER iptable_nat
Feb 10 15:53:22 SHAPER nf_conntrack_ipv4
Feb 10 15:53:22 SHAPER ipt_LOG
Feb 10 15:53:22 SHAPER ipt_MASQUERADE
Feb 10 15:53:22 SHAPER ipt_REDIRECT
Feb 10 15:53:22 SHAPER nf_nat
Feb 10 15:53:22 SHAPER nf_conntrack
Feb 10 15:53:22 SHAPER nfnetlink
Feb 10 15:53:22 SHAPER iptable_filter
Feb 10 15:53:22 SHAPER ip_tables
Feb 10 15:53:22 SHAPER x_tables
Feb 10 15:53:22 SHAPER 8021q
Feb 10 15:53:22 SHAPER tun
Feb 10 15:53:22 SHAPER tulip
Feb 10 15:53:22 SHAPER r8169
Feb 10 15:53:22 SHAPER sky2
Feb 10 15:53:22 SHAPER via_velocity
Feb 10 15:53:22 SHAPER via_rhine
Feb 10 15:53:22 SHAPER sis900
Feb 10 15:53:22 SHAPER ne2k_pci
Feb 10 15:53:22 SHAPER 8390
Feb 10 15:53:22 SHAPER skge
Feb 10 15:53:22 SHAPER tg3
Feb 10 15:53:22 SHAPER 8139too
Feb 10 15:53:22 SHAPER e1000
Feb 10 15:53:22 SHAPER e100
Feb 10 15:53:22 SHAPER usb_storage
Feb 10 15:53:22 SHAPER mtdblock
Feb 10 15:53:22 SHAPER mtd_blkdevs
Feb 10 15:53:22 SHAPER usbhid
Feb 10 15:53:22 SHAPER uhci_hcd
Feb 10 15:53:22 SHAPER ehci_hcd
Feb 10 15:53:22 SHAPER ohci_hcd
Feb 10 15:53:22 SHAPER usbcore
Feb 10 15:53:22 SHAPER
Feb 10 15:53:22 SHAPER [ 8271.779291]
Feb 10 15:53:22 SHAPER [ 8271.779307] Pid: 0, comm: swapper Not tainted
(2.6.24-build-0021 #26)
Feb 10 15:53:22 SHAPER [ 8271.779327] EIP: 0060:[<c01f0e5d>] EFLAGS: 00000082
CPU: 1
Feb 10 15:53:22 SHAPER [ 8271.779349] EIP is at __rb_rotate_right+0x5/0x50
Feb 10 15:53:22 SHAPER [ 8271.779366] EAX: f76494a4 EBX: f76494a4 ECX:
f76494a4 EDX: c1ff5f80
Feb 10 15:53:22 SHAPER [ 8271.779386] ESI: f76494a4 EDI: c1ff5f80 EBP:
00000000 ESP: f7c29c70
Feb 10 15:53:22 SHAPER [ 8271.779406] DS: 007b ES: 007b FS: 00d8 GS: 0000
SS: 0068
Feb 10 15:53:22 SHAPER [ 8271.779425] Process swapper (pid: 0, ti=f7c28000
task=f7c20a60 task.ti=f7c28000)
Feb 10 15:53:22 SHAPER
Feb 10 15:53:22 SHAPER [ 8271.779446] Stack:
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER c01f0ef4
Feb 10 15:53:22 SHAPER c1ff5f80
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER f76494a8
Feb 10 15:53:22 SHAPER c1ff5f78
Feb 10 15:53:22 SHAPER
Feb 10 15:53:22 SHAPER [ 8271.779493]
Feb 10 15:53:22 SHAPER [ 8271.779307] Pid: 0, comm: swapper Not tainted
(2.6.24-build-0021 #26)
Feb 10 15:53:22 SHAPER [ 8271.779327] EIP: 0060:[<c01f0e5d>] EFLAGS: 00000082
CPU: 1
Feb 10 15:53:22 SHAPER [ 8271.779349] EIP is at __rb_rotate_right+0x5/0x50
Feb 10 15:53:22 SHAPER [ 8271.779366] EAX: f76494a4 EBX: f76494a4 ECX:
f76494a4 EDX: c1ff5f80
Feb 10 15:53:22 SHAPER [ 8271.779386] ESI: f76494a4 EDI: c1ff5f80 EBP:
00000000 ESP: f7c29c70
Feb 10 15:53:22 SHAPER [ 8271.779406] DS: 007b ES: 007b FS: 00d8 GS: 0000
SS: 0068
Feb 10 15:53:22 SHAPER [ 8271.779425] Process swapper (pid: 0, ti=f7c28000
task=f7c20a60 task.ti=f7c28000)
Feb 10 15:53:22 SHAPER
Feb 10 15:53:22 SHAPER [ 8271.779446] Stack:
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER c01f0ef4
Feb 10 15:53:22 SHAPER c1ff5f80
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER f76494a8
Feb 10 15:53:22 SHAPER c1ff5f78
Feb 10 15:53:22 SHAPER
Feb 10 15:53:22 SHAPER [ 8271.779493]
Feb 10 15:53:22 SHAPER 00000000
Feb 10 15:53:22 SHAPER c0134741
Feb 10 15:53:22 SHAPER 00000001
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER f76494a4
Feb 10 15:53:22 SHAPER d2607800
Feb 10 15:53:22 SHAPER 00000778
Feb 10 15:53:22 SHAPER c1ff5f78
Feb 10 15:53:22 SHAPER
Feb 10 15:53:22 SHAPER [ 8271.779541]
Feb 10 15:53:22 SHAPER c0134d64
Feb 10 15:53:22 SHAPER 00fac3e0
Feb 10 15:53:22 SHAPER c1ff5f78
Feb 10 15:53:22 SHAPER 00000000
Feb 10 15:53:22 SHAPER 00000286
Feb 10 15:53:22 SHAPER f7649000
Feb 10 15:53:22 SHAPER f75f6800
Feb 10 15:53:22 SHAPER 00000000
Feb 10 15:53:22 SHAPER
Feb 10 15:53:22 SHAPER [ 8271.779589] Call Trace:
Feb 10 15:53:22 SHAPER [ 8271.779620] [<c01f0ef4>]
Feb 10 15:53:22 SHAPER rb_insert_color+0x4c/0xad
Feb 10 15:53:22 SHAPER [ 8271.779641] [<c0134741>]
Feb 10 15:53:22 SHAPER enqueue_hrtimer+0xd7/0xe2
Feb 10 15:53:22 SHAPER [ 8271.779661] [<c0134d64>]
Feb 10 15:53:22 SHAPER hrtimer_start+0xda/0xf4
Feb 10 15:53:22 SHAPER [ 8271.779682] [<c027ec43>]
Feb 10 15:53:22 SHAPER qdisc_watchdog_schedule+0x1e/0x21
Feb 10 15:53:22 SHAPER [ 8271.779704] [<f89f8fe6>]
Feb 10 15:53:22 SHAPER htb_dequeue+0x6ef/0x6fb [sch_htb]
Feb 10 15:53:22 SHAPER [ 8271.779726] [<f89e33e0>]
Feb 10 15:53:22 SHAPER sfq_drop+0x5e/0x221 [sch_sfq]
Feb 10 15:53:22 SHAPER [ 8271.779749] [<c027dfdf>]
Feb 10 15:53:22 SHAPER [ 8271.779749] [<c027dfdf>]
Feb 10 15:53:22 SHAPER tc_classify+0x17/0x7c
Feb 10 15:53:22 SHAPER [ 8271.779771] [<f89f76e1>]
Feb 10 15:53:22 SHAPER htb_classify+0xf0/0x157 [sch_htb]
Feb 10 15:53:22 SHAPER [ 8271.779794] [<c027da0e>]
Feb 10 15:53:22 SHAPER __qdisc_run+0x2a/0x163
Feb 10 15:53:22 SHAPER [ 8271.779814] [<c02728cc>]
Feb 10 15:53:22 SHAPER dev_queue_xmit+0x18b/0x2ab
Feb 10 15:53:22 SHAPER [ 8271.779835] [<f89eb189>]
Feb 10 15:53:22 SHAPER tcf_mirred+0x14b/0x168 [act_mirred]
Feb 10 15:53:22 SHAPER [ 8271.779857] [<f89eb03e>]
Feb 10 15:53:22 SHAPER tcf_mirred+0x0/0x168 [act_mirred]
Feb 10 15:53:22 SHAPER [ 8271.779878] [<c0280019>]
Feb 10 15:53:22 SHAPER tcf_action_exec+0x3d/0x6f
Feb 10 15:53:22 SHAPER [ 8271.779898] [<f89b55a2>]
Feb 10 15:53:22 SHAPER u32_classify+0x114/0x23e [cls_u32]
Feb 10 15:53:22 SHAPER [ 8271.779922] [<f897915e>]
Feb 10 15:53:22 SHAPER ipv4_confirm+0x34/0x39 [nf_conntrack_ipv4]
Feb 10 15:53:22 SHAPER [ 8271.779945] [<f897912a>]
Feb 10 15:53:22 SHAPER ipv4_confirm+0x0/0x39 [nf_conntrack_ipv4]
Feb 10 15:53:22 SHAPER [ 8271.779967] [<c027da81>]
Feb 10 15:53:22 SHAPER __qdisc_run+0x9d/0x163
Feb 10 15:53:22 SHAPER [ 8271.779989] [<c027ddf8>]
Feb 10 15:53:22 SHAPER tc_classify_compat+0x28/0x56
Feb 10 15:53:22 SHAPER [ 8271.780009] [<c027dfdf>]
Feb 10 15:53:22 SHAPER tc_classify+0x17/0x7c
Feb 10 15:53:22 SHAPER [ 8271.780028] [<c027010d>]
Feb 10 15:53:22 SHAPER netif_receive_skb+0x250/0x3e2
Feb 10 15:53:22 SHAPER [ 8271.780049] [<f89c70e3>]
Feb 10 15:53:22 SHAPER ingress_enqueue+0x16/0x4f [sch_ingress]
Feb 10 15:53:22 SHAPER [ 8271.780071] [<c02700f3>]
Feb 10 15:53:22 SHAPER netif_receive_skb+0x236/0x3e2
Feb 10 15:53:22 SHAPER [ 8271.780090] [<c028ac4d>]
Feb 10 15:53:22 SHAPER ip_rcv+0x1fc/0x237
Feb 10 15:53:22 SHAPER [ 8271.780109] [<c02835e6>]
Feb 10 15:53:22 SHAPER netlink_seq_next+0x1f/0xa8
Feb 10 15:53:22 SHAPER [ 8271.780131] [<f88d39a1>]
Feb 10 15:53:22 SHAPER e100_poll+0x157/0x26a [e100]
Feb 10 15:53:22 SHAPER [ 8271.780157] [<c0272110>]
Feb 10 15:53:22 SHAPER net_rx_action+0x8d/0x1ad
Feb 10 15:53:22 SHAPER [ 8271.780176] [<c02722d8>]
Feb 10 15:53:22 SHAPER net_tx_action+0xa8/0xcc
Feb 10 15:53:22 SHAPER [ 8271.780197] [<c0126a82>]
Feb 10 15:53:22 SHAPER __do_softirq+0x5d/0xc1
Feb 10 15:53:22 SHAPER [ 8271.780217] [<c0126b18>]
Feb 10 15:53:22 SHAPER do_softirq+0x32/0x36
Feb 10 15:53:22 SHAPER [ 8271.780236] [<c0126d6a>]
Feb 10 15:53:22 SHAPER irq_exit+0x38/0x6b
Feb 10 15:53:22 SHAPER [ 8271.780254] [<c01074f5>]
Feb 10 15:53:22 SHAPER do_IRQ+0x5c/0x73
Feb 10 15:53:22 SHAPER [ 8271.780275] [<c0106cc2>]
Feb 10 15:53:22 SHAPER do_nmi+0x97/0x24d
Feb 10 15:53:22 SHAPER [ 8271.780295] [<c010577b>]
Feb 10 15:53:22 SHAPER common_interrupt+0x23/0x28
Feb 10 15:53:22 SHAPER [ 8271.780317] [<c0103243>]
Feb 10 15:53:22 SHAPER mwait_idle_with_hints+0x3c/0x40
Feb 10 15:53:22 SHAPER [ 8271.780338] [<c0103247>]
Feb 10 15:53:22 SHAPER mwait_idle+0x0/0xa
Feb 10 15:53:22 SHAPER [ 8271.780356] [<c010357e>]
Feb 10 15:53:22 SHAPER cpu_idle+0x98/0xb9
Feb 10 15:53:22 SHAPER [ 8271.780380] =======================
Feb 10 15:53:22 SHAPER [ 8271.780396] Code:
Feb 10 15:53:22 SHAPER 09
Feb 10 15:53:22 SHAPER f0
Feb 10 15:53:22 SHAPER 85
Feb 10 15:53:22 SHAPER f6
Feb 10 15:53:22 SHAPER 89
Feb 10 15:53:22 SHAPER 02
Feb 10 15:53:22 SHAPER 74
Feb 10 15:53:22 SHAPER 0f
Feb 10 15:53:22 SHAPER 3b
Feb 10 15:53:22 SHAPER 5e
Feb 10 15:53:22 SHAPER 08
Feb 10 15:53:22 SHAPER 75
Feb 10 15:53:22 SHAPER 05
Feb 10 15:53:22 SHAPER 89
Feb 10 15:53:22 SHAPER 56
Feb 10 15:53:22 SHAPER 08
Feb 10 15:53:22 SHAPER eb
Feb 10 15:53:22 SHAPER 07
Feb 10 15:53:22 SHAPER 89
Feb 10 15:53:22 SHAPER 56
Feb 10 15:53:22 SHAPER 04
Feb 10 15:53:22 SHAPER eb
Feb 10 15:53:22 SHAPER 02
Feb 10 15:53:22 SHAPER 89
Feb 10 15:53:22 SHAPER 17
Feb 10 15:53:22 SHAPER 8b
Feb 10 15:53:22 SHAPER 03
Feb 10 15:53:22 SHAPER 83
Feb 10 15:53:22 SHAPER e0
Feb 10 15:53:22 SHAPER 03
Feb 10 15:53:22 SHAPER 09
Feb 10 15:53:22 SHAPER d0
Feb 10 15:53:22 SHAPER 89
Feb 10 15:53:22 SHAPER 03
Feb 10 15:53:22 SHAPER 5b
Feb 10 15:53:22 SHAPER 5e
Feb 10 15:53:22 SHAPER 5f
Feb 10 15:53:22 SHAPER c3
Feb 10 15:53:22 SHAPER 57
Feb 10 15:53:22 SHAPER 89
Feb 10 15:53:22 SHAPER d7
Feb 10 15:53:22 SHAPER 56
Feb 10 15:53:22 SHAPER 53
Feb 10 15:53:22 SHAPER
Feb 10 15:53:22 SHAPER c3
Feb 10 15:53:22 SHAPER 8b
Feb 10 15:53:22 SHAPER 50
Feb 10 15:53:22 SHAPER 08
Feb 10 15:53:22 SHAPER 8b
Feb 10 15:53:22 SHAPER 30
Feb 10 15:53:22 SHAPER 8b
Feb 10 15:53:22 SHAPER 4a
Feb 10 15:53:22 SHAPER 04
Feb 10 15:53:22 SHAPER 83
Feb 10 15:53:22 SHAPER e6
Feb 10 15:53:22 SHAPER fc
Feb 10 15:53:22 SHAPER 85
Feb 10 15:53:22 SHAPER c9
Feb 10 15:53:22 SHAPER 89
Feb 10 15:53:22 SHAPER 48
Feb 10 15:53:22 SHAPER 08
Feb 10 15:53:22 SHAPER 74
Feb 10 15:53:22 SHAPER 09
Feb 10 15:53:22 SHAPER 8b
Feb 10 15:53:22 SHAPER
--
Denys Fedoryshchenko
Technical Manager
Virtual ISP S.A.L.
^ permalink raw reply
* [PATCH] 3c509: convert to isa_driver and pnp_driver v5
From: Ondrej Zary @ 2008-02-10 21:03 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Stephen Hemminger, linux-kernel, netdev
In-Reply-To: <20080210051855.GA22064@infradead.org>
Hello,
this patch converts 3c509 driver to isa_driver and pnp_driver. The result is
that autoloading using udev and hibernation works with ISA PnP cards. It also
adds hibernation support for non-PnP ISA cards.
xcvr module parameter was removed as its value was not used.
Tested using 3 ISA cards in various combinations of PnP and non-PnP modes.
EISA and MCA only compile-tested.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
--- linux-2.6.24-orig/drivers/net/3c509.c 2008-01-27 19:48:19.000000000 +0100
+++ linux-2.6.24-pentium/drivers/net/3c509.c 2008-02-10 21:52:04.000000000 +0100
@@ -54,25 +54,24 @@
v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com>
- Increase *read_eeprom udelay to workaround oops with 2 cards.
v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
- - Introduce driver model for EISA cards.
+ - Introduce driver model for EISA cards.
+ v1.20 04Feb2008 Ondrej Zary <linux@rainbow-software.org>
+ - convert to isa_driver and pnp_driver and some cleanups
*/
#define DRV_NAME "3c509"
-#define DRV_VERSION "1.19b"
-#define DRV_RELDATE "08Nov2002"
+#define DRV_VERSION "1.20"
+#define DRV_RELDATE "04Feb2008"
/* A few values that may be tweaked. */
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (400*HZ/1000)
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 10;
#include <linux/module.h>
-#ifdef CONFIG_MCA
#include <linux/mca.h>
-#endif
-#include <linux/isapnp.h>
+#include <linux/isa.h>
+#include <linux/pnp.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
@@ -97,10 +96,6 @@
static char version[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
-#if defined(CONFIG_PM) && (defined(CONFIG_MCA) || defined(CONFIG_EISA))
-#define EL3_SUSPEND
-#endif
-
#ifdef EL3_DEBUG
static int el3_debug = EL3_DEBUG;
#else
@@ -111,6 +106,7 @@
* a global variable so that the mca/eisa probe routines can increment
* it */
static int el3_cards = 0;
+#define EL3_MAX_CARDS 8
/* To minimize the size of the driver source I only define operating
constants if they are used several times. You'll need the manual
@@ -119,7 +115,7 @@
#define EL3_DATA 0x00
#define EL3_CMD 0x0e
#define EL3_STATUS 0x0e
-#define EEPROM_READ 0x80
+#define EEPROM_READ 0x80
#define EL3_IO_EXTENT 16
@@ -168,23 +164,31 @@
*/
#define SKB_QUEUE_SIZE 64
+enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA };
+
struct el3_private {
struct net_device_stats stats;
- struct net_device *next_dev;
spinlock_t lock;
/* skb send-queue */
int head, size;
struct sk_buff *queue[SKB_QUEUE_SIZE];
- enum {
- EL3_MCA,
- EL3_PNP,
- EL3_EISA,
- } type; /* type of device */
- struct device *dev;
+ enum el3_cardtype type;
};
-static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/
-static struct net_device *el3_root_dev;
+static int id_port;
+static int current_tag;
+static struct net_device *el3_devs[EL3_MAX_CARDS];
+
+/* Parameters that may be passed into the module. */
+static int debug = -1;
+static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 10;
+#ifdef CONFIG_PNP
+static int nopnp;
+#endif
+static int __init el3_common_init(struct net_device *dev);
+static void el3_common_remove(struct net_device *dev);
static ushort id_read_eeprom(int index);
static ushort read_eeprom(int ioaddr, int index);
static int el3_open(struct net_device *dev);
@@ -199,23 +203,279 @@
static void el3_down(struct net_device *dev);
static void el3_up(struct net_device *dev);
static const struct ethtool_ops ethtool_ops;
-#ifdef EL3_SUSPEND
+#ifdef CONFIG_PM
static int el3_suspend(struct device *, pm_message_t);
static int el3_resume(struct device *);
-#else
-#define el3_suspend NULL
-#define el3_resume NULL
#endif
/* generic device remove for all device types */
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
static int el3_device_remove (struct device *device);
-#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
static void el3_poll_controller(struct net_device *dev);
#endif
+/* Return 0 on success, 1 on error, 2 when found already detected PnP card */
+static int el3_isa_id_sequence(__be16 *phys_addr)
+{
+ short lrs_state = 0xff;
+ int i;
+
+ /* ISA boards are detected by sending the ID sequence to the
+ ID_PORT. We find cards past the first by setting the 'current_tag'
+ on cards as they are found. Cards with their tag set will not
+ respond to subsequent ID sequences. */
+
+ outb(0x00, id_port);
+ outb(0x00, id_port);
+ for (i = 0; i < 255; i++) {
+ outb(lrs_state, id_port);
+ lrs_state <<= 1;
+ lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
+ }
+ /* For the first probe, clear all board's tag registers. */
+ if (current_tag == 0)
+ outb(0xd0, id_port);
+ else /* Otherwise kill off already-found boards. */
+ outb(0xd8, id_port);
+ if (id_read_eeprom(7) != 0x6d50)
+ return 1;
+ /* Read in EEPROM data, which does contention-select.
+ Only the lowest address board will stay "on-line".
+ 3Com got the byte order backwards. */
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(id_read_eeprom(i));
+#ifdef CONFIG_PNP
+ if (!nopnp) {
+ /* The ISA PnP 3c509 cards respond to the ID sequence too.
+ This check is needed in order not to register them twice. */
+ for (i = 0; i < el3_cards; i++) {
+ struct el3_private *lp = netdev_priv(el3_devs[i]);
+ if (lp->type == EL3_PNP
+ && !memcmp(phys_addr, el3_devs[i]->dev_addr,
+ ETH_ALEN)) {
+ if (el3_debug > 3)
+ printk(KERN_DEBUG "3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
+ phys_addr[0] & 0xff, phys_addr[0] >> 8,
+ phys_addr[1] & 0xff, phys_addr[1] >> 8,
+ phys_addr[2] & 0xff, phys_addr[2] >> 8);
+ /* Set the adaptor tag so that the next card can be found. */
+ outb(0xd0 + ++current_tag, id_port);
+ return 2;
+ }
+ }
+ }
+#endif /* CONFIG_PNP */
+ return 0;
+
+}
+
+static void __devinit el3_dev_fill(struct net_device *dev, __be16 *phys_addr,
+ int ioaddr, int irq, int if_port,
+ enum el3_cardtype type)
+{
+ struct el3_private *lp = netdev_priv(dev);
+
+ memcpy(dev->dev_addr, phys_addr, ETH_ALEN);
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+ dev->if_port = if_port;
+ lp->type = type;
+}
+
+static int __devinit el3_isa_match(struct device *pdev,
+ unsigned int ndev)
+{
+ struct net_device *dev;
+ int ioaddr, isa_irq, if_port, err;
+ unsigned int iobase;
+ __be16 phys_addr[3];
+
+ while ((err = el3_isa_id_sequence(phys_addr)) == 2)
+ ; /* Skip to next card when PnP card found */
+ if (err == 1)
+ return 0;
+
+ iobase = id_read_eeprom(8);
+ if_port = iobase >> 14;
+ ioaddr = 0x200 + ((iobase & 0x1f) << 4);
+ if (irq[el3_cards] > 1 && irq[el3_cards] < 16)
+ isa_irq = irq[el3_cards];
+ else
+ isa_irq = id_read_eeprom(9) >> 12;
+
+ dev = alloc_etherdev(sizeof(struct el3_private));
+ if (!dev)
+ return -ENOMEM;
+
+ netdev_boot_setup_check(dev);
+
+ if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) {
+ free_netdev(dev);
+ return 0;
+ }
+
+ /* Set the adaptor tag so that the next card can be found. */
+ outb(0xd0 + ++current_tag, id_port);
+
+ /* Activate the adaptor at the EEPROM location. */
+ outb((ioaddr >> 4) | 0xe0, id_port);
+
+ EL3WINDOW(0);
+ if (inw(ioaddr) != 0x6d50) {
+ free_netdev(dev);
+ return 0;
+ }
+
+ /* Free the interrupt so that some other card can use it. */
+ outw(0x0f00, ioaddr + WN0_IRQ);
+
+ el3_dev_fill(dev, phys_addr, ioaddr, isa_irq, if_port, EL3_ISA);
+ dev_set_drvdata(pdev, dev);
+ if (el3_common_init(dev)) {
+ free_netdev(dev);
+ return 0;
+ }
+
+ el3_devs[el3_cards++] = dev;
+ return 1;
+}
+
+static int __devexit el3_isa_remove(struct device *pdev,
+ unsigned int ndev)
+{
+ el3_device_remove(pdev);
+ dev_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int el3_isa_suspend(struct device *dev, unsigned int n,
+ pm_message_t state)
+{
+ current_tag = 0;
+ return el3_suspend(dev, state);
+}
+
+static int el3_isa_resume(struct device *dev, unsigned int n)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ int ioaddr = ndev->base_addr, err;
+ __be16 phys_addr[3];
+
+ while ((err = el3_isa_id_sequence(phys_addr)) == 2)
+ ; /* Skip to next card when PnP card found */
+ if (err == 1)
+ return 0;
+ /* Set the adaptor tag so that the next card can be found. */
+ outb(0xd0 + ++current_tag, id_port);
+ /* Enable the card */
+ outb((ioaddr >> 4) | 0xe0, id_port);
+ EL3WINDOW(0);
+ if (inw(ioaddr) != 0x6d50)
+ return 1;
+ /* Free the interrupt so that some other card can use it. */
+ outw(0x0f00, ioaddr + WN0_IRQ);
+ return el3_resume(dev);
+}
+#endif
+
+static struct isa_driver el3_isa_driver = {
+ .match = el3_isa_match,
+ .remove = __devexit_p(el3_isa_remove),
+#ifdef CONFIG_PM
+ .suspend = el3_isa_suspend,
+ .resume = el3_isa_resume,
+#endif
+ .driver = {
+ .name = "3c509"
+ },
+};
+static int isa_registered;
+
+#ifdef CONFIG_PNP
+static struct pnp_device_id el3_pnp_ids[] = {
+ { .id = "TCM5090" }, /* 3Com Etherlink III (TP) */
+ { .id = "TCM5091" }, /* 3Com Etherlink III */
+ { .id = "TCM5094" }, /* 3Com Etherlink III (combo) */
+ { .id = "TCM5095" }, /* 3Com Etherlink III (TPO) */
+ { .id = "TCM5098" }, /* 3Com Etherlink III (TPC) */
+ { .id = "PNP80f7" }, /* 3Com Etherlink III compatible */
+ { .id = "PNP80f8" }, /* 3Com Etherlink III compatible */
+ { .id = "" }
+};
+MODULE_DEVICE_TABLE(pnp, el3_pnp_ids);
+
+static int __devinit el3_pnp_probe(struct pnp_dev *pdev,
+ const struct pnp_device_id *id)
+{
+ short i;
+ int ioaddr, irq, if_port;
+ u16 phys_addr[3];
+ struct net_device *dev = NULL;
+ int err;
+
+ ioaddr = pnp_port_start(pdev, 0);
+ if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-pnp"))
+ return -EBUSY;
+ irq = pnp_irq(pdev, 0);
+ EL3WINDOW(0);
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(read_eeprom(ioaddr, i));
+ if_port = read_eeprom(ioaddr, 8) >> 14;
+ dev = alloc_etherdev(sizeof(struct el3_private));
+ if (!dev) {
+ release_region(ioaddr, EL3_IO_EXTENT);
+ return -ENOMEM;
+ }
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ netdev_boot_setup_check(dev);
+
+ el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_PNP);
+ pnp_set_drvdata(pdev, dev);
+ err = el3_common_init(dev);
+
+ if (err) {
+ pnp_set_drvdata(pdev, NULL);
+ free_netdev(dev);
+ return err;
+ }
+
+ el3_devs[el3_cards++] = dev;
+ return 0;
+}
+
+static void __devexit el3_pnp_remove(struct pnp_dev *pdev)
+{
+ el3_common_remove(pnp_get_drvdata(pdev));
+ pnp_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int el3_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
+{
+ return el3_suspend(&pdev->dev, state);
+}
+
+static int el3_pnp_resume(struct pnp_dev *pdev)
+{
+ return el3_resume(&pdev->dev);
+}
+#endif
+
+static struct pnp_driver el3_pnp_driver = {
+ .name = "3c509",
+ .id_table = el3_pnp_ids,
+ .probe = el3_pnp_probe,
+ .remove = __devexit_p(el3_pnp_remove),
+#ifdef CONFIG_PM
+ .suspend = el3_pnp_suspend,
+ .resume = el3_pnp_resume,
+#endif
+};
+static int pnp_registered;
+#endif /* CONFIG_PNP */
+
#ifdef CONFIG_EISA
static struct eisa_device_id el3_eisa_ids[] = {
{ "TCM5092" },
@@ -230,13 +490,14 @@
static struct eisa_driver el3_eisa_driver = {
.id_table = el3_eisa_ids,
.driver = {
- .name = "3c509",
+ .name = "3c579",
.probe = el3_eisa_probe,
.remove = __devexit_p (el3_device_remove),
.suspend = el3_suspend,
.resume = el3_resume,
}
};
+static int eisa_registered;
#endif
#ifdef CONFIG_MCA
@@ -271,45 +532,9 @@
.resume = el3_resume,
},
};
+static int mca_registered;
#endif /* CONFIG_MCA */
-#if defined(__ISAPNP__)
-static struct isapnp_device_id el3_isapnp_adapters[] __initdata = {
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090),
- (long) "3Com Etherlink III (TP)" },
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5091),
- (long) "3Com Etherlink III" },
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5094),
- (long) "3Com Etherlink III (combo)" },
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5095),
- (long) "3Com Etherlink III (TPO)" },
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5098),
- (long) "3Com Etherlink III (TPC)" },
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f7),
- (long) "3Com Etherlink III compatible" },
- { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
- ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f8),
- (long) "3Com Etherlink III compatible" },
- { } /* terminate list */
-};
-
-static __be16 el3_isapnp_phys_addr[8][3];
-static int nopnp;
-#endif /* __ISAPNP__ */
-
-/* With the driver model introduction for EISA devices, both init
- * and cleanup have been split :
- * - EISA devices probe/remove starts in el3_eisa_probe/el3_device_remove
- * - MCA/ISA still use el3_probe
- *
- * Both call el3_common_init/el3_common_remove. */
-
static int __init el3_common_init(struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
@@ -360,231 +585,11 @@
static void el3_common_remove (struct net_device *dev)
{
- struct el3_private *lp = netdev_priv(dev);
-
- (void) lp; /* Keep gcc quiet... */
-#if defined(__ISAPNP__)
- if (lp->type == EL3_PNP)
- pnp_device_detach(to_pnp_dev(lp->dev));
-#endif
-
unregister_netdev (dev);
release_region(dev->base_addr, EL3_IO_EXTENT);
free_netdev (dev);
}
-static int __init el3_probe(int card_idx)
-{
- struct net_device *dev;
- struct el3_private *lp;
- short lrs_state = 0xff, i;
- int ioaddr, irq, if_port;
- __be16 phys_addr[3];
- static int current_tag;
- int err = -ENODEV;
-#if defined(__ISAPNP__)
- static int pnp_cards;
- struct pnp_dev *idev = NULL;
- int pnp_found = 0;
-
- if (nopnp == 1)
- goto no_pnp;
-
- for (i=0; el3_isapnp_adapters[i].vendor != 0; i++) {
- int j;
- while ((idev = pnp_find_dev(NULL,
- el3_isapnp_adapters[i].vendor,
- el3_isapnp_adapters[i].function,
- idev))) {
- if (pnp_device_attach(idev) < 0)
- continue;
- if (pnp_activate_dev(idev) < 0) {
-__again:
- pnp_device_detach(idev);
- continue;
- }
- if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0))
- goto __again;
- ioaddr = pnp_port_start(idev, 0);
- if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509 PnP")) {
- pnp_device_detach(idev);
- return -EBUSY;
- }
- irq = pnp_irq(idev, 0);
- if (el3_debug > 3)
- printk ("ISAPnP reports %s at i/o 0x%x, irq %d\n",
- (char*) el3_isapnp_adapters[i].driver_data, ioaddr, irq);
- EL3WINDOW(0);
- for (j = 0; j < 3; j++)
- el3_isapnp_phys_addr[pnp_cards][j] =
- phys_addr[j] =
- htons(read_eeprom(ioaddr, j));
- if_port = read_eeprom(ioaddr, 8) >> 14;
- dev = alloc_etherdev(sizeof (struct el3_private));
- if (!dev) {
- release_region(ioaddr, EL3_IO_EXTENT);
- pnp_device_detach(idev);
- return -ENOMEM;
- }
-
- SET_NETDEV_DEV(dev, &idev->dev);
- pnp_cards++;
-
- netdev_boot_setup_check(dev);
- pnp_found = 1;
- goto found;
- }
- }
-no_pnp:
-#endif /* __ISAPNP__ */
-
- /* Select an open I/O location at 0x1*0 to do contention select. */
- for ( ; id_port < 0x200; id_port += 0x10) {
- if (!request_region(id_port, 1, "3c509"))
- continue;
- outb(0x00, id_port);
- outb(0xff, id_port);
- if (inb(id_port) & 0x01){
- release_region(id_port, 1);
- break;
- } else
- release_region(id_port, 1);
- }
- if (id_port >= 0x200) {
- /* Rare -- do we really need a warning? */
- printk(" WARNING: No I/O port available for 3c509 activation.\n");
- return -ENODEV;
- }
-
- /* Next check for all ISA bus boards by sending the ID sequence to the
- ID_PORT. We find cards past the first by setting the 'current_tag'
- on cards as they are found. Cards with their tag set will not
- respond to subsequent ID sequences. */
-
- outb(0x00, id_port);
- outb(0x00, id_port);
- for(i = 0; i < 255; i++) {
- outb(lrs_state, id_port);
- lrs_state <<= 1;
- lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
- }
-
- /* For the first probe, clear all board's tag registers. */
- if (current_tag == 0)
- outb(0xd0, id_port);
- else /* Otherwise kill off already-found boards. */
- outb(0xd8, id_port);
-
- if (id_read_eeprom(7) != 0x6d50) {
- return -ENODEV;
- }
-
- /* Read in EEPROM data, which does contention-select.
- Only the lowest address board will stay "on-line".
- 3Com got the byte order backwards. */
- for (i = 0; i < 3; i++) {
- phys_addr[i] = htons(id_read_eeprom(i));
- }
-
-#if defined(__ISAPNP__)
- if (nopnp == 0) {
- /* The ISA PnP 3c509 cards respond to the ID sequence.
- This check is needed in order not to register them twice. */
- for (i = 0; i < pnp_cards; i++) {
- if (phys_addr[0] == el3_isapnp_phys_addr[i][0] &&
- phys_addr[1] == el3_isapnp_phys_addr[i][1] &&
- phys_addr[2] == el3_isapnp_phys_addr[i][2])
- {
- if (el3_debug > 3)
- printk("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
- phys_addr[0] & 0xff, phys_addr[0] >> 8,
- phys_addr[1] & 0xff, phys_addr[1] >> 8,
- phys_addr[2] & 0xff, phys_addr[2] >> 8);
- /* Set the adaptor tag so that the next card can be found. */
- outb(0xd0 + ++current_tag, id_port);
- goto no_pnp;
- }
- }
- }
-#endif /* __ISAPNP__ */
-
- {
- unsigned int iobase = id_read_eeprom(8);
- if_port = iobase >> 14;
- ioaddr = 0x200 + ((iobase & 0x1f) << 4);
- }
- irq = id_read_eeprom(9) >> 12;
-
- dev = alloc_etherdev(sizeof (struct el3_private));
- if (!dev)
- return -ENOMEM;
-
- netdev_boot_setup_check(dev);
-
- /* Set passed-in IRQ or I/O Addr. */
- if (dev->irq > 1 && dev->irq < 16)
- irq = dev->irq;
-
- if (dev->base_addr) {
- if (dev->mem_end == 0x3c509 /* Magic key */
- && dev->base_addr >= 0x200 && dev->base_addr <= 0x3e0)
- ioaddr = dev->base_addr & 0x3f0;
- else if (dev->base_addr != ioaddr)
- goto out;
- }
-
- if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) {
- err = -EBUSY;
- goto out;
- }
-
- /* Set the adaptor tag so that the next card can be found. */
- outb(0xd0 + ++current_tag, id_port);
-
- /* Activate the adaptor at the EEPROM location. */
- outb((ioaddr >> 4) | 0xe0, id_port);
-
- EL3WINDOW(0);
- if (inw(ioaddr) != 0x6d50)
- goto out1;
-
- /* Free the interrupt so that some other card can use it. */
- outw(0x0f00, ioaddr + WN0_IRQ);
-
-#if defined(__ISAPNP__)
- found: /* PNP jumps here... */
-#endif /* __ISAPNP__ */
-
- memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
- dev->base_addr = ioaddr;
- dev->irq = irq;
- dev->if_port = if_port;
- lp = netdev_priv(dev);
-#if defined(__ISAPNP__)
- lp->dev = &idev->dev;
- if (pnp_found)
- lp->type = EL3_PNP;
-#endif
- err = el3_common_init(dev);
-
- if (err)
- goto out1;
-
- el3_cards++;
- lp->next_dev = el3_root_dev;
- el3_root_dev = dev;
- return 0;
-
-out1:
-#if defined(__ISAPNP__)
- if (idev)
- pnp_device_detach(idev);
-#endif
-out:
- free_netdev(dev);
- return err;
-}
-
#ifdef CONFIG_MCA
static int __init el3_mca_probe(struct device *device)
{
@@ -596,7 +601,6 @@
* redone for multi-card detection by ZP Gu (zpg@castle.net)
* now works as a module */
- struct el3_private *lp;
short i;
int ioaddr, irq, if_port;
u16 phys_addr[3];
@@ -613,7 +617,7 @@
irq = pos5 & 0x0f;
- printk("3c529: found %s at slot %d\n",
+ printk(KERN_INFO "3c529: found %s at slot %d\n",
el3_mca_adapter_names[mdev->index], slot + 1);
/* claim the slot */
@@ -626,7 +630,7 @@
irq = mca_device_transform_irq(mdev, irq);
ioaddr = mca_device_transform_ioport(mdev, ioaddr);
if (el3_debug > 2) {
- printk("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
+ printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
}
EL3WINDOW(0);
for (i = 0; i < 3; i++) {
@@ -641,13 +645,7 @@
netdev_boot_setup_check(dev);
- memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
- dev->base_addr = ioaddr;
- dev->irq = irq;
- dev->if_port = if_port;
- lp = netdev_priv(dev);
- lp->dev = device;
- lp->type = EL3_MCA;
+ el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
device->driver_data = dev;
err = el3_common_init(dev);
@@ -657,7 +655,7 @@
return -ENOMEM;
}
- el3_cards++;
+ el3_devs[el3_cards++] = dev;
return 0;
}
@@ -666,7 +664,6 @@
#ifdef CONFIG_EISA
static int __init el3_eisa_probe (struct device *device)
{
- struct el3_private *lp;
short i;
int ioaddr, irq, if_port;
u16 phys_addr[3];
@@ -678,7 +675,7 @@
edev = to_eisa_device (device);
ioaddr = edev->base_addr;
- if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
+ if (!request_region(ioaddr, EL3_IO_EXTENT, "3c579-eisa"))
return -EBUSY;
/* Change the register set to the configuration window 0. */
@@ -700,13 +697,7 @@
netdev_boot_setup_check(dev);
- memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
- dev->base_addr = ioaddr;
- dev->irq = irq;
- dev->if_port = if_port;
- lp = netdev_priv(dev);
- lp->dev = device;
- lp->type = EL3_EISA;
+ el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA);
eisa_set_drvdata (edev, dev);
err = el3_common_init(dev);
@@ -716,12 +707,11 @@
return err;
}
- el3_cards++;
+ el3_devs[el3_cards++] = dev;
return 0;
}
#endif
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
/* This remove works for all device types.
*
* The net dev must be stored in the driver_data field */
@@ -734,7 +724,6 @@
el3_common_remove (dev);
return 0;
}
-#endif
/* Read a word from the EEPROM using the regular EEPROM access register.
Assume that we are in register window zero.
@@ -749,7 +738,7 @@
}
/* Read a word from the EEPROM when in the ISA ID probe state. */
-static ushort __init id_read_eeprom(int index)
+static ushort id_read_eeprom(int index)
{
int bit, word = 0;
@@ -765,7 +754,7 @@
word = (word << 1) + (inb(id_port) & 0x01);
if (el3_debug > 3)
- printk(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
+ printk(KERN_DEBUG " 3c509 EEPROM word %d %#4.4x.\n", index, word);
return word;
}
@@ -787,13 +776,13 @@
EL3WINDOW(0);
if (el3_debug > 3)
- printk("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
+ printk(KERN_DEBUG "%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
el3_up(dev);
if (el3_debug > 3)
- printk("%s: Opened 3c509 IRQ %d status %4.4x.\n",
+ printk(KERN_DEBUG "%s: Opened 3c509 IRQ %d status %4.4x.\n",
dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
return 0;
@@ -806,7 +795,7 @@
int ioaddr = dev->base_addr;
/* Transmitter timeout, serious problems. */
- printk("%s: transmit timed out, Tx_status %2.2x status %4.4x "
+ printk(KERN_WARNING "%s: transmit timed out, Tx_status %2.2x status %4.4x "
"Tx FIFO room %d.\n",
dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
inw(ioaddr + TX_FREE));
@@ -831,7 +820,7 @@
lp->stats.tx_bytes += skb->len;
if (el3_debug > 4) {
- printk("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
+ printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
dev->name, skb->len, inw(ioaddr + EL3_STATUS));
}
#if 0
@@ -840,7 +829,7 @@
ushort status = inw(ioaddr + EL3_STATUS);
if (status & 0x0001 /* IRQ line active, missed one. */
&& inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */
- printk("%s: Missed interrupt, status then %04x now %04x"
+ printk(KERN_DEBUG "%s: Missed interrupt, status then %04x now %04x"
" Tx %2.2x Rx %4.4x.\n", dev->name, status,
inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
inw(ioaddr + RX_STATUS));
@@ -914,7 +903,7 @@
if (el3_debug > 4) {
status = inw(ioaddr + EL3_STATUS);
- printk("%s: interrupt, status %4.4x.\n", dev->name, status);
+ printk(KERN_DEBUG "%s: interrupt, status %4.4x.\n", dev->name, status);
}
while ((status = inw(ioaddr + EL3_STATUS)) &
@@ -925,7 +914,7 @@
if (status & TxAvailable) {
if (el3_debug > 5)
- printk(" TX room bit was handled.\n");
+ printk(KERN_DEBUG " TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue (dev);
@@ -964,7 +953,7 @@
}
if (--i < 0) {
- printk("%s: Infinite loop in interrupt, status %4.4x.\n",
+ printk(KERN_ERR "%s: Infinite loop in interrupt, status %4.4x.\n",
dev->name, status);
/* Clear all interrupts. */
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -975,7 +964,7 @@
}
if (el3_debug > 4) {
- printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
+ printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", dev->name,
inw(ioaddr + EL3_STATUS));
}
spin_unlock(&lp->lock);
@@ -1450,7 +1439,7 @@
}
/* Power Management support functions */
-#ifdef EL3_SUSPEND
+#ifdef CONFIG_PM
static int
el3_suspend(struct device *pdev, pm_message_t state)
@@ -1500,79 +1489,102 @@
return 0;
}
-#endif /* EL3_SUSPEND */
-
-/* Parameters that may be passed into the module. */
-static int debug = -1;
-static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+#endif /* CONFIG_PM */
module_param(debug,int, 0);
module_param_array(irq, int, NULL, 0);
-module_param_array(xcvr, int, NULL, 0);
module_param(max_interrupt_work, int, 0);
MODULE_PARM_DESC(debug, "debug level (0-6)");
MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)");
MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
-#if defined(__ISAPNP__)
+#ifdef CONFIG_PNP
module_param(nopnp, int, 0);
MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
-MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters);
-#endif /* __ISAPNP__ */
-MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver");
+#endif /* CONFIG_PNP */
+MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B, 3c529, 3c579) ethernet driver");
MODULE_LICENSE("GPL");
static int __init el3_init_module(void)
{
int ret = 0;
- el3_cards = 0;
if (debug >= 0)
el3_debug = debug;
- el3_root_dev = NULL;
- while (el3_probe(el3_cards) == 0) {
- if (irq[el3_cards] > 1)
- el3_root_dev->irq = irq[el3_cards];
- if (xcvr[el3_cards] >= 0)
- el3_root_dev->if_port = xcvr[el3_cards];
- el3_cards++;
+#ifdef CONFIG_PNP
+ if (!nopnp) {
+ ret = pnp_register_driver(&el3_pnp_driver);
+ if (!ret)
+ pnp_registered = 1;
+ }
+#endif
+ /* Select an open I/O location at 0x1*0 to do ISA contention select. */
+ /* Start with 0x110 to avoid some sound cards.*/
+ for (id_port = 0x110 ; id_port < 0x200; id_port += 0x10) {
+ if (!request_region(id_port, 1, "3c509-control"))
+ continue;
+ outb(0x00, id_port);
+ outb(0xff, id_port);
+ if (inb(id_port) & 0x01)
+ break;
+ else
+ release_region(id_port, 1);
+ }
+ if (id_port >= 0x200) {
+ id_port = 0;
+ printk(KERN_ERR "No I/O port available for 3c509 activation.\n");
+ } else {
+ ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
+ if (!ret)
+ isa_registered = 1;
}
-
#ifdef CONFIG_EISA
ret = eisa_driver_register(&el3_eisa_driver);
+ if (!ret)
+ eisa_registered = 1;
#endif
#ifdef CONFIG_MCA
- {
- int err = mca_register_driver(&el3_mca_driver);
- if (ret == 0)
- ret = err;
- }
+ ret = mca_register_driver(&el3_mca_driver);
+ if (!ret)
+ mca_registered = 1;
+#endif
+
+#ifdef CONFIG_PNP
+ if (pnp_registered)
+ ret = 0;
+#endif
+ if (isa_registered)
+ ret = 0;
+#ifdef CONFIG_EISA
+ if (eisa_registered)
+ ret = 0;
+#endif
+#ifdef CONFIG_MCA
+ if (mca_registered)
+ ret = 0;
#endif
return ret;
}
static void __exit el3_cleanup_module(void)
{
- struct net_device *next_dev;
-
- while (el3_root_dev) {
- struct el3_private *lp = netdev_priv(el3_root_dev);
-
- next_dev = lp->next_dev;
- el3_common_remove (el3_root_dev);
- el3_root_dev = next_dev;
- }
-
+#ifdef CONFIG_PNP
+ if (pnp_registered)
+ pnp_unregister_driver(&el3_pnp_driver);
+#endif
+ if (isa_registered)
+ isa_unregister_driver(&el3_isa_driver);
+ if (id_port)
+ release_region(id_port, 1);
#ifdef CONFIG_EISA
- eisa_driver_unregister (&el3_eisa_driver);
+ if (eisa_registered)
+ eisa_driver_unregister(&el3_eisa_driver);
#endif
#ifdef CONFIG_MCA
- mca_unregister_driver(&el3_mca_driver);
+ if (mca_registered)
+ mca_unregister_driver(&el3_mca_driver);
#endif
}
module_init (el3_init_module);
module_exit (el3_cleanup_module);
-
--
Ondrej Zary
^ permalink raw reply
* Netfilter fixes to 2.6.24-git
From: Jan Engelhardt @ 2008-02-10 21:02 UTC (permalink / raw)
To: netdev
Cc: Linux Kernel Mailing List, Netfilter Developer Mailing List,
davem, kaber, torvalds
Hi to everyone,
I have been unable to reach the netfilter and net maintainers the past
week regarding inclusion of patches, but most importantly a group of
fixes at [0]-[3]. I am kind of at a loss here but to turn up the volume
and write to more people on how to proceed.
thanks,
Jan
[0] http://marc.info/?l=netfilter-devel&m=120230633916142&w=2 (Overview)
[1] http://marc.info/?l=netfilter-devel&m=120230634016145&w=2
[2] http://marc.info/?l=netfilter-devel&m=120230634216156&w=2
[3] http://marc.info/?l=netfilter-devel&m=120230634616162&w=2
^ permalink raw reply
* [PATCH] drivers/net/sis190: fix section mismatch warning in sis190_get_mac_addr
From: Sergio Luis @ 2008-02-10 20:56 UTC (permalink / raw)
To: LKML; +Cc: Francois Romieu, netdev
Fix following warnings:
WARNING: drivers/net/sis190.o(.text+0x103): Section mismatch in reference from the function sis190_get_mac_addr() to the function .devinit.text:sis190_get_mac_addr_from_apc()
WARNING: drivers/net/sis190.o(.text+0x10e): Section mismatch in reference from the function sis190_get_mac_addr() to the function .devinit.text:sis190_get_mac_addr_from_eeprom()
Annotate sis190_get_mac_addr() with __devinit.
Signed-off-by: Sergio Luis <sergio@uece.br>
sis190.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff -urN linux-2.6.24-git22.orig/drivers/net/sis190.c linux-2.6.24-git22/drivers/net/sis190.c
--- linux-2.6.24-git22.orig/drivers/net/sis190.c 2008-02-10 16:56:37.000000000 -0300
+++ linux-2.6.24-git22/drivers/net/sis190.c 2008-02-10 17:38:36.000000000 -0300
@@ -1630,7 +1630,8 @@
SIS_PCI_COMMIT();
}
-static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
+static int __devinit sis190_get_mac_addr(struct pci_dev *pdev,
+ struct net_device *dev)
{
u8 from;
^ permalink raw reply
* [PATCH 5/8] drivers/net/mv643xx_eth.c: Use FIELD_SIZEOF
From: Julia Lawall @ 2008-02-10 20:13 UTC (permalink / raw)
To: dale, mlachwani, netdev; +Cc: linux-kernel, kernel-janitors
From: Julia Lawall <julia@diku.dk>
Robert P.J. Day proposed to use the macro FIELD_SIZEOF in replace of code
that matches its definition.
The modification was made using the following semantic patch
(http://www.emn.fr/x-info/coccinelle/)
// <smpl>
@haskernel@
@@
#include <linux/kernel.h>
@depends on haskernel@
type t;
identifier f;
@@
- (sizeof(((t*)0)->f))
+ FIELD_SIZEOF(t, f)
@depends on haskernel@
type t;
identifier f;
@@
- sizeof(((t*)0)->f)
+ FIELD_SIZEOF(t, f)
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
---
diff -u -p a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
--- a/drivers/net/mv643xx_eth.c 2008-02-08 08:58:12.000000000 +0100
+++ b/drivers/net/mv643xx_eth.c 2008-02-10 18:00:09.000000000 +0100
@@ -3155,7 +3155,7 @@ struct mv643xx_stats {
int stat_offset;
};
-#define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \
+#define MV643XX_STAT(m) FIELD_SIZEOF(struct mv643xx_private, m), \
offsetof(struct mv643xx_private, m)
static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
^ permalink raw reply
* Re: [PATCH] New device for DM9601 usb net driver
From: Peter Korsgaard @ 2008-02-10 19:36 UTC (permalink / raw)
To: Robert Brockway, jeff; +Cc: netdev
In-Reply-To: <Pine.LNX.4.64.0802071046540.24824@castor.opentrend.net>
>>>>> "Robert" == Robert Brockway <robert@timetraveller.org> writes:
Robert> Hi Peter. I've verified that the Hirose USB-100 (0x0a47,
Robert> 0x9601) is a clone of the DAVICOM DM9601. I patched dm9601.c
Robert> to identify this device and now have these in production.
Robert> Unified diff against 2.6.24 attached.
Thanks!
Acked-by: Peter Korsgaard <jacmet@sunsite.dk>
Robert> Cheers,
Robert> Rob
Robert> --
Robert> "With sufficient thrust, pigs fly just fine..."
Robert> -- RFC 1925 "The Twelve Networking Truths"
Robert> --- drivers/net/usb/dm9601.c.old 2008-01-27 00:51:50.000000000 -0500
Robert> +++ drivers/net/usb/dm9601.c 2008-02-07 10:27:40.000000000 -0500
Robert> @@ -590,6 +590,10 @@ static const struct usb_device_id produc
Robert> USB_DEVICE(0x0a46, 0x8515), /* ADMtek ADM8515 USB NIC */
Robert> .driver_info = (unsigned long)&dm9601_info,
Robert> },
Robert> + {
Robert> + USB_DEVICE(0x0a47, 0x9601), /* Hirose USB-100 */
Robert> + .driver_info = (unsigned long)&dm9601_info,
Robert> + },
Robert> {}, // END
Robert> };
--
Bye, Peter Korsgaard
^ permalink raw reply
* Re: [PATCH][AX25] ax25_ds_timer: use mod_timer instead of add_timer
From: Jann Traschewski @ 2008-02-10 18:23 UTC (permalink / raw)
To: 'Jarek Poplawski', netdev
Cc: 'Ralf Baechle', 'David Miller'
In-Reply-To: <20080206091413.GE4496@ff.dom.local>
Patches from Jarek applied (incl. both "testing" patches). Machine is stable
since 2 days now.
Regards,
Jann
> -----Ursprüngliche Nachricht-----
> Von: Jarek Poplawski [mailto:jarkao2@gmail.com]
> Gesendet: Mittwoch, 6. Februar 2008 10:14
> An: netdev@vger.kernel.org
> Cc: Ralf Baechle; Jann Traschewski; David Miller
> Betreff: [PATCH][AX25] ax25_ds_timer: use mod_timer instead
> of add_timer
>
> On Wed, Feb 06, 2008 at 08:15:09AM +0000, Jarek Poplawski wrote:
> > On Wed, Feb 06, 2008 at 07:45:29AM +0000, Jarek Poplawski wrote:
> > ...
> > > From: Jann Traschewski <jann@gmx.de>
> > > Subject: SMP with AX.25
> ...
>
>
> [AX25] ax25_ds_timer: use mod_timer instead of add_timer
>
> This patch changes current use of: init_timer(), add_timer()
> and del_timer() to setup_timer() with mod_timer(), which
> should be safer anyway.
>
>
> Reported-by: Jann Traschewski <jann@gmx.de>
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
>
> ---
>
> include/net/ax25.h | 1 +
> net/ax25/ax25_dev.c | 2 +-
> net/ax25/ax25_ds_timer.c | 12 ++++--------
> 3 files changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/include/net/ax25.h b/include/net/ax25.h index
> 3f0236f..717e219 100644
> --- a/include/net/ax25.h
> +++ b/include/net/ax25.h
> @@ -324,6 +324,7 @@ extern void ax25_dama_on(ax25_cb *);
> extern void ax25_dama_off(ax25_cb *);
>
> /* ax25_ds_timer.c */
> +extern void ax25_ds_setup_timer(ax25_dev *);
> extern void ax25_ds_set_timer(ax25_dev *); extern void
> ax25_ds_del_timer(ax25_dev *); extern void
> ax25_ds_timer(ax25_cb *); diff --git a/net/ax25/ax25_dev.c
> b/net/ax25/ax25_dev.c index 528c874..a7a0e0c 100644
> --- a/net/ax25/ax25_dev.c
> +++ b/net/ax25/ax25_dev.c
> @@ -82,7 +82,7 @@ void ax25_dev_device_up(struct net_device *dev)
> ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT;
>
> #if defined(CONFIG_AX25_DAMA_SLAVE) ||
> defined(CONFIG_AX25_DAMA_MASTER)
> - init_timer(&ax25_dev->dama.slave_timer);
> + ax25_ds_setup_timer(ax25_dev);
> #endif
>
> spin_lock_bh(&ax25_dev_lock);
> diff --git a/net/ax25/ax25_ds_timer.c
> b/net/ax25/ax25_ds_timer.c index c4e3b02..2ce79df 100644
> --- a/net/ax25/ax25_ds_timer.c
> +++ b/net/ax25/ax25_ds_timer.c
> @@ -40,13 +40,10 @@ static void ax25_ds_timeout(unsigned long);
> * 1/10th of a second.
> */
>
> -static void ax25_ds_add_timer(ax25_dev *ax25_dev)
> +void ax25_ds_setup_timer(ax25_dev *ax25_dev)
> {
> - struct timer_list *t = &ax25_dev->dama.slave_timer;
> - t->data = (unsigned long) ax25_dev;
> - t->function = &ax25_ds_timeout;
> - t->expires = jiffies + HZ;
> - add_timer(t);
> + setup_timer(&ax25_dev->dama.slave_timer, ax25_ds_timeout,
> + (unsigned long)ax25_dev);
> }
>
> void ax25_ds_del_timer(ax25_dev *ax25_dev) @@ -60,10 +57,9
> @@ void ax25_ds_set_timer(ax25_dev *ax25_dev)
> if (ax25_dev == NULL) /* paranoia */
> return;
>
> - del_timer(&ax25_dev->dama.slave_timer);
> ax25_dev->dama.slave_timeout =
>
> msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10;
> - ax25_ds_add_timer(ax25_dev);
> + mod_timer(&ax25_dev->dama.slave_timer, jiffies + HZ);
> }
>
> /*
^ permalink raw reply
* Re: [PATCH][AX25] ax25_ds_timer: use mod_timer instead of add_timer
From: Bernard Pidoux F6BVP @ 2008-02-10 18:07 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: Ralf Baechle DL5RB, Jann Traschewski, Linux Netdev List
In-Reply-To: <20080209193905.GA2754@ami.dom.local>
Hi Jarek,
Sorry, I should have been more explicit about the patches I applied.
My CPU is an Intel Core 2 duo and I compiled 2.6.24 with SMP option.
I applied 3 patches you have submitted for ax25 before I observed the
possible locking.
That is :
mkiss patch
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index cfcd15a..30c9b3b 100644
[AX25] ax25_timer: use mod_timer instead of add_timer
[AX25] ax25_ds_timer: use mod_timer instead of add_timer
I also applied 4 patches for rose.ko I sent to the list a while ago.
But for this report I did not installed any ROSE driver nor application.
I will try your new patch version 2 and report any possible change.
Regards,
Bernard Pidoux,
F6BVP
Jarek Poplawski wrote:
> On Sat, Feb 09, 2008 at 07:44:50PM +0100, Bernard Pidoux F6BVP wrote:
>> Hi,
>>
>> With AX25 patches applied I still get this possible circular locking
>> message.
>
> Hi Bernard,
>
> Could you confirm which exactly patches did you try? Is this vanilla
> 2.6.24 plus these two: ax25_timer and ax25_ds_timer or something more?
> And I'm not sure what do you mean by "still": the warning came back
> just after these last patches? At least these timer patches don't seem
> to change anything around locking?
>
> Thanks for testing this,
> Jarek P.
>
>
^ permalink raw reply
* Re: [patch 2.6.24-git] net/enc28j60: low power mode
From: David Brownell @ 2008-02-10 17:46 UTC (permalink / raw)
To: Claudio Lanconelli; +Cc: netdev
In-Reply-To: <47AAE99D.1000908@eptar.com>
Keep enc28j60 chips in low-power mode when they're not in use.
At typically 120 mA, these chips run hot even when idle; this
low power mode cuts that power usage by a factor of around 100.
This version provides a generic routine to poll a register until
its masked value equals some value ... e.g. bit set or cleared.
It's basically what the previous wait_phy_ready() did, but this
version is generalized to support the handshaking needed to
enter and exit low power mode.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
---
drivers/net/enc28j60.c | 81 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 57 insertions(+), 24 deletions(-)
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -400,26 +400,31 @@ enc28j60_packet_write(struct enc28j60_ne
mutex_unlock(&priv->lock);
}
-/*
- * Wait until the PHY operation is complete.
- */
-static int wait_phy_ready(struct enc28j60_net *priv)
+static unsigned long msec20_to_jiffies;
+
+static int poll_ready(struct enc28j60_net *priv, u8 reg, u8 mask, u8 val)
{
- unsigned long timeout = jiffies + 20 * HZ / 1000;
- int ret = 1;
+ unsigned long timeout = jiffies + msec20_to_jiffies;
/* 20 msec timeout read */
- while (nolock_regb_read(priv, MISTAT) & MISTAT_BUSY) {
+ while ((nolock_regb_read(priv, reg) & mask) != val) {
if (time_after(jiffies, timeout)) {
if (netif_msg_drv(priv))
- printk(KERN_DEBUG DRV_NAME
- ": PHY ready timeout!\n");
- ret = 0;
- break;
+ dev_dbg(&priv->spi->dev,
+ "reg %02x ready timeout!\n", reg);
+ return -ETIMEDOUT;
}
cpu_relax();
}
- return ret;
+ return 0;
+}
+
+/*
+ * Wait until the PHY operation is complete.
+ */
+static int wait_phy_ready(struct enc28j60_net *priv)
+{
+ return poll_ready(priv, MISTAT, MISTAT_BUSY, 0) ? 0 : 1;
}
/*
@@ -594,6 +599,32 @@ static void nolock_txfifo_init(struct en
nolock_regw_write(priv, ETXNDL, end);
}
+/*
+ * Low power mode shrinks power consumption about 100x, so we'd like
+ * the chip to be in that mode whenever it's inactive. (However, we
+ * can't stay in lowpower mode during suspend with WOL active.)
+ */
+static void enc28j60_lowpower(struct enc28j60_net *priv, bool is_low)
+{
+ if (netif_msg_drv(priv))
+ dev_dbg(&priv->spi->dev, "%s power...\n",
+ is_low ? "low" : "high");
+
+ mutex_lock(&priv->lock);
+ if (is_low) {
+ nolock_reg_bfclr(priv, ECON1, ECON1_RXEN);
+ poll_ready(priv, ESTAT, ESTAT_RXBUSY, 0);
+ poll_ready(priv, ECON1, ECON1_TXRTS, 0);
+ /* ECON2_VRPS was set during initialization */
+ nolock_reg_bfset(priv, ECON2, ECON2_PWRSV);
+ } else {
+ nolock_reg_bfclr(priv, ECON2, ECON2_PWRSV);
+ poll_ready(priv, ESTAT, ESTAT_CLKRDY, ESTAT_CLKRDY);
+ /* caller sets ECON1_RXEN */
+ }
+ mutex_unlock(&priv->lock);
+}
+
static int enc28j60_hw_init(struct enc28j60_net *priv)
{
u8 reg;
@@ -612,8 +643,8 @@ static int enc28j60_hw_init(struct enc28
priv->tx_retry_count = 0;
priv->max_pk_counter = 0;
priv->rxfilter = RXFILTER_NORMAL;
- /* enable address auto increment */
- nolock_regb_write(priv, ECON2, ECON2_AUTOINC);
+ /* enable address auto increment and voltage regulator powersave */
+ nolock_regb_write(priv, ECON2, ECON2_AUTOINC | ECON2_VRPS);
nolock_rxfifo_init(priv, RXSTART_INIT, RXEND_INIT);
nolock_txfifo_init(priv, TXSTART_INIT, TXEND_INIT);
@@ -690,7 +721,7 @@ static int enc28j60_hw_init(struct enc28
static void enc28j60_hw_enable(struct enc28j60_net *priv)
{
- /* enable interrutps */
+ /* enable interrupts */
if (netif_msg_hw(priv))
printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n",
__FUNCTION__);
@@ -726,15 +757,12 @@ enc28j60_setlink(struct net_device *ndev
int ret = 0;
if (!priv->hw_enable) {
- if (autoneg == AUTONEG_DISABLE && speed == SPEED_10) {
+ /* link is in low power mode now; duplex setting
+ * will take effect on next enc28j60_hw_init().
+ */
+ if (autoneg == AUTONEG_DISABLE && speed == SPEED_10)
priv->full_duplex = (duplex == DUPLEX_FULL);
- if (!enc28j60_hw_init(priv)) {
- if (netif_msg_drv(priv))
- dev_err(&ndev->dev,
- "hw_reset() failed\n");
- ret = -EINVAL;
- }
- } else {
+ else {
if (netif_msg_link(priv))
dev_warn(&ndev->dev,
"unsupported link setting\n");
@@ -1307,7 +1335,7 @@ static int enc28j60_net_open(struct net_
}
return -EADDRNOTAVAIL;
}
- /* Reset the hardware here */
+ /* Reset the hardware here (and take it out of low power mode) */
enc28j60_hw_disable(priv);
if (!enc28j60_hw_init(priv)) {
if (netif_msg_ifup(priv))
@@ -1337,6 +1365,7 @@ static int enc28j60_net_close(struct net
printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
enc28j60_hw_disable(priv);
+ enc28j60_lowpower(priv, true);
netif_stop_queue(dev);
return 0;
@@ -1537,6 +1566,8 @@ static int __devinit enc28j60_probe(stru
dev->watchdog_timeo = TX_TIMEOUT;
SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops);
+ enc28j60_lowpower(priv, true);
+
ret = register_netdev(dev);
if (ret) {
if (netif_msg_probe(priv))
@@ -1582,6 +1613,8 @@ static struct spi_driver enc28j60_driver
static int __init enc28j60_init(void)
{
+ msec20_to_jiffies = msecs_to_jiffies(20);
+
return spi_register_driver(&enc28j60_driver);
}
^ permalink raw reply
* Re: [patch 2.6.24-git] net/enc28j60: oops fix, low power mode
From: David Brownell @ 2008-02-10 17:54 UTC (permalink / raw)
To: Claudio Lanconelli; +Cc: netdev
In-Reply-To: <47AAE32A.7070105@eptar.com>
On Thursday 07 February 2008, Claudio Lanconelli wrote:
> David Brownell wrote:
> > How long did that take? I did about four dozen
> >
> > ifconfig eth1 up
> > sleep 3
> > ifconfig eth1 down
> >
> > cycles ... it worked fine. The "sleep" was to let the link
> > negotiation complete.
> >
> >
> After a couple of :
>
> ifconfig eth0 down
> (wait just 1 second)
> ifconfig eth0 up
>
> the network is frozen.
>
> If I do another
> ifconfig eth0 down
> (wait just 1 second)
> ifconfig eth0 up
>
> restarts.
> It's random, no rule.
I write a shell loop to do that, and added a "ping -c2" too.
If that was done before the "sleep 1" no packets flowed.
Afterwards, no problem -- ever.
(And outside the loop, "ethool -s eth1 duplex full".)
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox