* Re: [PATCH 4/7] net: emaclite: Add support for little-endian platforms
From: David Miller @ 2010-09-29 6:27 UTC (permalink / raw)
To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ
Cc: eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, duyl-gjFFaj9aHVfQT0dZR+AlfA,
netdev-u79uwXL29TY76Z2rM5mHXA, linnj-gjFFaj9aHVfQT0dZR+AlfA,
edgar.iglesias-Re5JQEeQqe8AvxtiuMwx3w,
john.williams-g5w7nrANp4BDPfheJLI6IQ
In-Reply-To: <20100929061146.GA2439-MrY2KI0G/OVr83L8+7iqerDks+cytr/Z@public.gmane.org>
From: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Date: Wed, 29 Sep 2010 15:11:46 +0900
> On Wed, Sep 29, 2010 at 03:52:15PM +1000, Michal Simek wrote:
>> Upcomming Microblaze is little endian that's why is necessary
>> to fix protocol and length loading.
>>
>> Signed-off-by: Michal Simek <monstr-pSz03upnqPeHXe+LvDLADg@public.gmane.org>
>> CC: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
>> CC: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
>> CC: Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> CC: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> CC: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> CC: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
>
> This should go via davem, but it looks correct to me.
>
> Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
It doesn't need to, the microblaze guys can integrate this directly:
Acked-by: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
^ permalink raw reply
* Re: [PATCH] ip_gre: CONFIG_IPV6_MODULE support
From: Eric Dumazet @ 2010-09-29 6:24 UTC (permalink / raw)
To: Herbert Xu; +Cc: davem, netdev, Patrick McHardy
In-Reply-To: <20100929043642.GA3660@gondor.apana.org.au>
Le mercredi 29 septembre 2010 à 13:36 +0900, Herbert Xu a écrit :
> On Wed, Sep 29, 2010 at 06:24:55AM +0200, Eric Dumazet wrote:
> >
> > Well, we all know icmpv6_cleanup() is not really called (or can we
> > really unload ipv6 ?).
> >
> > But unregister_icmpv6_send() should be the first call in it.
>
> Do we really need to support IPV6=m and GRE=y? It might be simpler
> to just behave as if IPv6 is off when this combination is given.
>
> Cheers,
Well, sometimes people wants to :
/etc/modprobe.conf
install ipv6 /bin/true
Yet, be able to load ip_gre as a module
so IPV6=m, GRE=m,
^ permalink raw reply
* Re: [PATCH 4/7] net: emaclite: Add support for little-endian platforms
From: Grant Likely @ 2010-09-29 6:11 UTC (permalink / raw)
To: Michal Simek
Cc: linux-kernel, john.williams, edgar.iglesias, duyl, linnj,
microblaze-uclinux, David S. Miller, Eric Dumazet, netdev,
devicetree-discuss
In-Reply-To: <1285739538-29058-5-git-send-email-monstr@monstr.eu>
On Wed, Sep 29, 2010 at 03:52:15PM +1000, Michal Simek wrote:
> Upcomming Microblaze is little endian that's why is necessary
> to fix protocol and length loading.
>
> Signed-off-by: Michal Simek <monstr@monstr.eu>
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Grant Likely <grant.likely@secretlab.ca>
> CC: Eric Dumazet <eric.dumazet@gmail.com>
> CC: netdev@vger.kernel.org
> CC: linux-kernel@vger.kernel.org
> CC: devicetree-discuss@lists.ozlabs.org
This should go via davem, but it looks correct to me.
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> drivers/net/xilinx_emaclite.c | 8 ++++----
> 1 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
> index 71122ee..533ebb1 100644
> --- a/drivers/net/xilinx_emaclite.c
> +++ b/drivers/net/xilinx_emaclite.c
> @@ -430,8 +430,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
> }
>
> /* Get the protocol type of the ethernet frame that arrived */
> - proto_type = ((in_be32(addr + XEL_HEADER_OFFSET +
> - XEL_RXBUFF_OFFSET) >> XEL_HEADER_SHIFT) &
> + proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET +
> + XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) &
> XEL_RPLR_LENGTH_MASK);
>
> /* Check if received ethernet frame is a raw ethernet frame
> @@ -439,9 +439,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
> if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
>
> if (proto_type == ETH_P_IP) {
> - length = ((in_be32(addr +
> + length = ((ntohl(in_be32(addr +
> XEL_HEADER_IP_LENGTH_OFFSET +
> - XEL_RXBUFF_OFFSET) >>
> + XEL_RXBUFF_OFFSET)) >>
> XEL_HEADER_SHIFT) &
> XEL_RPLR_LENGTH_MASK);
> length += ETH_HLEN + ETH_FCS_LEN;
> --
> 1.5.5.1
>
^ permalink raw reply
* [PATCH 4/7] net: emaclite: Add support for little-endian platforms
From: Michal Simek @ 2010-09-29 5:52 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Eric Dumazet, microblaze-uclinux-rVRm/Wmeqae7NGdpmJTKYQ,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
duyl-gjFFaj9aHVfQT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
linnj-gjFFaj9aHVfQT0dZR+AlfA,
edgar.iglesias-Re5JQEeQqe8AvxtiuMwx3w, David S. Miller,
john.williams-g5w7nrANp4BDPfheJLI6IQ
In-Reply-To: <1285739538-29058-4-git-send-email-monstr-pSz03upnqPeHXe+LvDLADg@public.gmane.org>
Upcomming Microblaze is little endian that's why is necessary
to fix protocol and length loading.
Signed-off-by: Michal Simek <monstr-pSz03upnqPeHXe+LvDLADg@public.gmane.org>
CC: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
CC: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
CC: Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
---
drivers/net/xilinx_emaclite.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 71122ee..533ebb1 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -430,8 +430,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
}
/* Get the protocol type of the ethernet frame that arrived */
- proto_type = ((in_be32(addr + XEL_HEADER_OFFSET +
- XEL_RXBUFF_OFFSET) >> XEL_HEADER_SHIFT) &
+ proto_type = ((ntohl(in_be32(addr + XEL_HEADER_OFFSET +
+ XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) &
XEL_RPLR_LENGTH_MASK);
/* Check if received ethernet frame is a raw ethernet frame
@@ -439,9 +439,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
if (proto_type == ETH_P_IP) {
- length = ((in_be32(addr +
+ length = ((ntohl(in_be32(addr +
XEL_HEADER_IP_LENGTH_OFFSET +
- XEL_RXBUFF_OFFSET) >>
+ XEL_RXBUFF_OFFSET)) >>
XEL_HEADER_SHIFT) &
XEL_RPLR_LENGTH_MASK);
length += ETH_HLEN + ETH_FCS_LEN;
--
1.5.5.1
^ permalink raw reply related
* Re: [PATCH] ip_gre: CONFIG_IPV6_MODULE support
From: David Miller @ 2010-09-29 5:38 UTC (permalink / raw)
To: herbert; +Cc: eric.dumazet, netdev, kaber
In-Reply-To: <20100928.214132.226782961.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Tue, 28 Sep 2010 21:41:32 -0700 (PDT)
> Eric, please cook up a patch which does this, I think the
> magic Kconfig dependency formula for this is:
>
> depends on IPV6 || IPV6=n
>
> Thanks!
Nevermind, I took care of it :-)
--------------------
ip_gre: Fix dependencies wrt. ipv6.
The GRE tunnel driver needs to invoke icmpv6 helpers in the
ipv6 stack when ipv6 support is enabled.
Therefore if IPV6 is enabled, we have to enforce that GRE's
enabling (modular or static) matches that of ipv6.
Reported-by: Patrick McHardy <kaber@trash.net>
Reported-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/Kconfig | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 571f895..72380a3 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -217,6 +217,7 @@ config NET_IPIP
config NET_IPGRE
tristate "IP: GRE tunnels over IP"
+ depends on IPV6 || IPV6=n
help
Tunneling means encapsulating data of one protocol type within
another protocol and sending it over a channel that understands the
--
1.7.3
^ permalink raw reply related
* [PATCH net-next] tcp: tcp_enter_quickack_mode can be static
From: Stephen Hemminger @ 2010-09-29 5:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Function only used in tcp_input.c
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
---
include/net/tcp.h | 2 --
net/ipv4/tcp_input.c | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
--- a/net/ipv4/tcp_input.c 2010-09-29 14:00:54.145805254 +0900
+++ b/net/ipv4/tcp_input.c 2010-09-29 14:24:27.595831651 +0900
@@ -182,7 +182,7 @@ static void tcp_incr_quickack(struct soc
icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
}
-void tcp_enter_quickack_mode(struct sock *sk)
+static void tcp_enter_quickack_mode(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
tcp_incr_quickack(sk);
--- a/include/net/tcp.h 2010-09-29 14:27:53.543307029 +0900
+++ b/include/net/tcp.h 2010-09-29 14:28:10.435891279 +0900
@@ -346,8 +346,6 @@ static inline void tcp_dec_quickack_mode
}
}
-extern void tcp_enter_quickack_mode(struct sock *sk);
-
#define TCP_ECN_OK 1
#define TCP_ECN_QUEUE_CWR 2
#define TCP_ECN_DEMAND_CWR 4
^ permalink raw reply
* Re: [PATCH linux-2.6 v2] IPv6: Create temporary address if none exists.
From: David Miller @ 2010-09-29 5:25 UTC (permalink / raw)
To: gwurster
Cc: kuznet, pekkas, jmorris, yoshfuji, kaber, shemminger,
eric.dumazet, herbert, ebiederm, netdev, linux-kernel
In-Reply-To: <20100927170430.GA7106@adams.ccsl.carleton.ca>
From: Glenn Wurster <gwurster@scs.carleton.ca>
Date: Mon, 27 Sep 2010 13:04:30 -0400
> If privacy extentions are enabled, but no current temporary address exists,
> then create one when we get a router advertisement.
>
> Version 2, now with 100% fewer line wraps. Thanks to David Miller for
> pointing out the line wrapping issue.
>
> Signed-off-by: Glenn Wurster <gwurster@scs.carleton.ca>
The existing code is correct from what I can tell.
Variable "create" is true when "ifp == NULL" and "valid_lft != 0"
And RFC 3041 explicitly states in section 3.3:
When a new public address is created as described in [ADDRCONF]
(because the prefix advertised does not match the prefix of any
address already assigned to the interface, and Valid Lifetime
in the option is not zero), also create a new temporary address.
Your patch is going to cause us to create a temporary address even
when valid_lft is zero, which the RFC says we should not do.
That goes against what the RFC tells us to do, so I can only conclude
that your patch is not correct.
I'm not applying this, sorry.
^ permalink raw reply
* Re: [PATCH] ip_gre: CONFIG_IPV6_MODULE support
From: David Miller @ 2010-09-29 4:41 UTC (permalink / raw)
To: herbert; +Cc: eric.dumazet, netdev, kaber
In-Reply-To: <20100929043642.GA3660@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 29 Sep 2010 13:36:42 +0900
> On Wed, Sep 29, 2010 at 06:24:55AM +0200, Eric Dumazet wrote:
>>
>> Well, we all know icmpv6_cleanup() is not really called (or can we
>> really unload ipv6 ?).
>>
>> But unregister_icmpv6_send() should be the first call in it.
>
> Do we really need to support IPV6=m and GRE=y? It might be simpler
> to just behave as if IPv6 is off when this combination is given.
I think we should make it so that the Kconfig rule only allows
"m" or "n" for IP_GRE when IPV6=m
That's how we handle this kind of situation elsewhere, f.e. see
bonding.
Eric, please cook up a patch which does this, I think the
magic Kconfig dependency formula for this is:
depends on IPV6 || IPV6=n
Thanks!
^ permalink raw reply
* Re: [PATCH] ip_gre: CONFIG_IPV6_MODULE support
From: Herbert Xu @ 2010-09-29 4:36 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, netdev, Patrick McHardy
In-Reply-To: <1285734295.22570.25.camel@edumazet-laptop>
On Wed, Sep 29, 2010 at 06:24:55AM +0200, Eric Dumazet wrote:
>
> Well, we all know icmpv6_cleanup() is not really called (or can we
> really unload ipv6 ?).
>
> But unregister_icmpv6_send() should be the first call in it.
Do we really need to support IPV6=m and GRE=y? It might be simpler
to just behave as if IPv6 is off when this combination is given.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: WiMAX linux firmware pull request
From: Inaky Perez-Gonzalez @ 2010-09-29 4:27 UTC (permalink / raw)
To: David Woodhouse; +Cc: wimax@linuxwimax.org, netdev@vger.kernel.org
In-Reply-To: <1285728768.814.74.camel@macbook.infradead.org>
On Tue, 2010-09-28 at 19:52 -0700, David Woodhouse wrote:
> On Tue, 2010-09-28 at 11:46 -0700, Inaky Perez-Gonzalez wrote:
> > The 1.3 version is purged as it is not supported anymore.
>
> Not supported by newer kernels? Or "if you are using something that
> requires the 1.3 firmware, you can just fuck off and die", along the
> lines of what we say to users of the 2.4 kernel?
Along those lines -- basically 1.3 was an experimental release and if
you have that firmware, you won't be able to connect to anything than a
very specific test setup in a lab. The code is still there because it is
just two perfectly isolated paths (if curious, check what goes with the
i2400m_le_v1_3() test) that I forgot to excise out.
> We shouldn't drop stuff from linux-firmware.git until there really is
> *no* reason to need it any more. We shouldn't force people to keep
> linux-firmware in step with their kernel; they should always be able to
> use the latest.
Yes, I am aware of that. That's why 1.4 is kept there -- 1.3 is an
special case because as I said above, it can't be used in the real world
of WiMAX,
> When I get home from Tokyo I'll be working on a way to specify min/max
> kernel versions for each firmware image, along with a 'make install'
> target which lets you say "drop anything which is only relevant to
> kernels < 2.6.35' or whatever.
That looks pretty sensible :)
^ permalink raw reply
* Re: [PATCH] ip_gre: CONFIG_IPV6_MODULE support
From: Eric Dumazet @ 2010-09-29 4:24 UTC (permalink / raw)
To: Herbert Xu; +Cc: davem, netdev, Patrick McHardy
In-Reply-To: <1285733911.22570.20.camel@edumazet-laptop>
Le mercredi 29 septembre 2010 à 06:18 +0200, Eric Dumazet a écrit :
> diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
> index 03e62f9..25e9ad6 100644
> --- a/net/ipv6/icmp.c
> +++ b/net/ipv6/icmp.c
> @@ -862,6 +862,7 @@ int __init icmpv6_init(void)
> err = -EAGAIN;
> if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0)
> goto fail;
> + register_icmpv6_send(icmpv6_send);
> return 0;
>
> fail:
> @@ -874,6 +875,7 @@ void icmpv6_cleanup(void)
> {
> unregister_pernet_subsys(&icmpv6_sk_ops);
> inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
> + unregister_icmpv6_send();
> }
Well, we all know icmpv6_cleanup() is not really called (or can we
really unload ipv6 ?).
But unregister_icmpv6_send() should be the first call in it.
Updated patch :
[PATCH v2] ipv6: introduce call_icmpv6_send()
ip_gre module has a dependency against IPv6:
It needs to call icmpv6_send(), while this symbol is available only if
IPv6 module is loaded (or static)
Introduce call_icmpv6_send(), provided in core network, to indirectly
call icmpv6_send() function if available.
Reported-by: Patrick McHardy <kaber@trash.net>
Reported-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/net/icmp.h | 6 ++++++
net/ipv4/icmp.c | 33 +++++++++++++++++++++++++++++++++
net/ipv4/ip_gre.c | 2 +-
net/ipv6/icmp.c | 2 ++
4 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 6e991e0..ec45a4f 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -48,4 +48,10 @@ extern void icmp_out_count(struct net *net, unsigned char type);
/* Move into dst.h ? */
extern int xrlim_allow(struct dst_entry *dst, int timeout);
+extern int register_icmpv6_send(void (*func)(struct sk_buff *skb, u8 type,
+ u8 code, __u32 info));
+extern int unregister_icmpv6_send(void);
+extern void call_icmpv6_send(struct sk_buff *skb, u8 type,
+ u8 code, __u32 info);
+
#endif /* _ICMP_H */
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index a0d847c..4c5b817 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -1217,3 +1217,36 @@ int __init icmp_init(void)
{
return register_pernet_subsys(&icmp_sk_ops);
}
+
+
+/* wrappers to call icmpv6_send() if ipv6 module is loaded */
+
+static void __rcu (*icmpv6_send_ptr)(struct sk_buff *skb, u8 type, u8 code,
+ __u32 info);
+
+int register_icmpv6_send(void (*func)(struct sk_buff *skb, u8 type, u8 code,
+ __u32 info))
+{
+ rcu_assign_pointer(icmpv6_send_ptr, func);
+ return 0;
+}
+EXPORT_SYMBOL(register_icmpv6_send);
+
+int unregister_icmpv6_send(void)
+{
+ rcu_assign_pointer(icmpv6_send_ptr, NULL);
+ synchronize_rcu();
+ return 0;
+}
+EXPORT_SYMBOL(unregister_icmpv6_send);
+
+/* called with rcu_read_lock */
+void call_icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
+{
+ void (*func)(struct sk_buff *skb, u8 type, u8 code, __u32 info);
+
+ func = rcu_dereference(icmpv6_send_ptr);
+ if (func)
+ (*func)(skb, type, code, info);
+}
+EXPORT_SYMBOL(call_icmpv6_send);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 35c93e8..6cbd37c 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -788,7 +788,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) {
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+ call_icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
ip_rt_put(rt);
goto tx_error;
}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 03e62f9..2d0f56b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -862,6 +862,7 @@ int __init icmpv6_init(void)
err = -EAGAIN;
if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0)
goto fail;
+ register_icmpv6_send(icmpv6_send);
return 0;
fail:
@@ -872,6 +873,7 @@ fail:
void icmpv6_cleanup(void)
{
+ unregister_icmpv6_send();
unregister_pernet_subsys(&icmpv6_sk_ops);
inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
}
^ permalink raw reply related
* Re: [PATCH] ip_gre: CONFIG_IPV6_MODULE support
From: Eric Dumazet @ 2010-09-29 4:18 UTC (permalink / raw)
To: Herbert Xu; +Cc: davem, netdev, Patrick McHardy
In-Reply-To: <1285663738.2607.30.camel@edumazet-laptop>
Le mardi 28 septembre 2010 à 10:48 +0200, Eric Dumazet a écrit :
> Le mardi 28 septembre 2010 à 17:41 +0900, Herbert Xu a écrit :
> > Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > > ipv6 can be a module, we should test CONFIG_IPV6 and CONFIG_IPV6_MODULE
> > > to enable ipv6 bits in ip_gre.
> > >
> > > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> >
> > To do this safely, we also need to disallow IPV6=m and GRE=y.
> >
> > Cheers,
>
I even remember Patrick warned about this 30 months ago.... Doh...
http://www.kerneltrap.com/mailarchive/linux-netdev/2008/1/22/590393
Given its now rare ipv6 is not loaded, what about following patch ?
Thanks !
Tested here, with a non loaded ipv6 module.
[PATCH] ipv6: introduce call_icmpv6_send()
ip_gre module has a dependency against IPv6:
It needs to call icmpv6_send(), while this symbol is available only if
IPv6 module is loaded (or static)
Introduce call_icmpv6_send(), provided in core network, to indirectly
call icmpv6_send() function if available.
Reported-by: Patrick McHardy <kaber@trash.net>
Reported-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/net/icmp.h | 6 ++++++
net/ipv4/icmp.c | 33 +++++++++++++++++++++++++++++++++
net/ipv4/ip_gre.c | 2 +-
net/ipv6/icmp.c | 2 ++
4 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 6e991e0..ec45a4f 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -48,4 +48,10 @@ extern void icmp_out_count(struct net *net, unsigned char type);
/* Move into dst.h ? */
extern int xrlim_allow(struct dst_entry *dst, int timeout);
+extern int register_icmpv6_send(void (*func)(struct sk_buff *skb, u8 type,
+ u8 code, __u32 info));
+extern int unregister_icmpv6_send(void);
+extern void call_icmpv6_send(struct sk_buff *skb, u8 type,
+ u8 code, __u32 info);
+
#endif /* _ICMP_H */
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index a0d847c..4c5b817 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -1217,3 +1217,36 @@ int __init icmp_init(void)
{
return register_pernet_subsys(&icmp_sk_ops);
}
+
+
+/* wrappers to call icmpv6_send() if ipv6 module is loaded */
+
+static void __rcu (*icmpv6_send_ptr)(struct sk_buff *skb, u8 type, u8 code,
+ __u32 info);
+
+int register_icmpv6_send(void (*func)(struct sk_buff *skb, u8 type, u8 code,
+ __u32 info))
+{
+ rcu_assign_pointer(icmpv6_send_ptr, func);
+ return 0;
+}
+EXPORT_SYMBOL(register_icmpv6_send);
+
+int unregister_icmpv6_send(void)
+{
+ rcu_assign_pointer(icmpv6_send_ptr, NULL);
+ synchronize_rcu();
+ return 0;
+}
+EXPORT_SYMBOL(unregister_icmpv6_send);
+
+/* called with rcu_read_lock */
+void call_icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
+{
+ void (*func)(struct sk_buff *skb, u8 type, u8 code, __u32 info);
+
+ func = rcu_dereference(icmpv6_send_ptr);
+ if (func)
+ (*func)(skb, type, code, info);
+}
+EXPORT_SYMBOL(call_icmpv6_send);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 35c93e8..6cbd37c 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -788,7 +788,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
if (mtu >= IPV6_MIN_MTU && mtu < skb->len - tunnel->hlen + gre_hlen) {
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+ call_icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
ip_rt_put(rt);
goto tx_error;
}
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 03e62f9..25e9ad6 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -862,6 +862,7 @@ int __init icmpv6_init(void)
err = -EAGAIN;
if (inet6_add_protocol(&icmpv6_protocol, IPPROTO_ICMPV6) < 0)
goto fail;
+ register_icmpv6_send(icmpv6_send);
return 0;
fail:
@@ -874,6 +875,7 @@ void icmpv6_cleanup(void)
{
unregister_pernet_subsys(&icmpv6_sk_ops);
inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
+ unregister_icmpv6_send();
}
^ permalink raw reply related
* Re: [RFC PATCH 2/2] macvtap: TX zero copy between guest and host kernel
From: Shirley Ma @ 2010-09-29 3:24 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Arnd Bergmann, Avi Kivity, Xin, Xiaohui, David Miller, netdev,
kvm, linux-kernel
In-Reply-To: <1284562354.2573.12.camel@localhost.localdomain>
Hello Michael,
On Wed, 2010-09-15 at 07:52 -0700, Shirley Ma wrote:
> > > Don't you think once I address vhost_add_used_and_signal update
> > > issue, it is a simple and complete patch for macvtap TX zero copy?
> > >
> > > Thanks
> > > Shirley
> >
> > I like the fact that the patch is simple. Unfortunately
> > I suspect it'll stop being simple by the time it's complete :)
>
> I can make a try. :)
I compared several approaches for addressing the issue being raised here
on how/when to update vhost_add_used_and_signal. The simple approach I
have found is:
1. Adding completion field in struct virtqueue;
2. when it is a zero copy packet, put vhost thread wait for completion
to update vhost_add_used_and_signal;
3. passing vq from vhost to macvtap as skb destruct_arg;
4. when skb is freed for the last reference, signal vq completion
The test results show same performance as the original patch. How do you
think? If it sounds good to you. I will resubmit this reversion patch.
The patch still keeps as simple as it was before. :)
Thanks
Shirley
^ permalink raw reply
* Re: [ABI REVIEW][PATCH 0/8] Namespace file descriptors
From: Rémi Denis-Courmont @ 2010-09-29 3:09 UTC (permalink / raw)
To: Eric W. Biederman, Linux Containers; +Cc: netdev
In-Reply-To: <m1ocborgq7.fsf@fess.ebiederm.org>
(Trimming To/Cc heavily)
Hello,
On Thursday 23 September 2010, Eric W. Biederman wrote:
> Introduce file for manipulating namespaces and related syscalls.
> files:
> /proc/self/ns/<nstype>
>
> syscalls:
> int setns(unsigned long nstype, int fd);
> socketat(int nsfd, int family, int type, int protocol);
>
> Netlink attribute:
> IFLA_NS_FD int fd.
I have not reviewed the code, but that seems quite nice. At Nokia, we already
use network namespaces to implement the Multimedia Message Service.
Inconveniently enough, that is HTTP/TCP/IP in a dedicated IP namespace.
Similarly, I expect this could be useful to implement the IMS, if/when mobile
operators start using it (that does not mean Nokia will or will not do it).
Using netns, we avoided overlapping with the normal Internet connectivity.
setns() would be much more convenient than fork()+unshare().
--
Rémi Denis-Courmont
http://www.remlab.net/
^ permalink raw reply
* [PATCH 3] drivers/net/usb/qcusbnet: Spelling and extern int debug cleanups
From: Joe Perches @ 2010-09-29 3:09 UTC (permalink / raw)
To: Elly Jones; +Cc: netdev, dbrownell, mjg59, jglasgow, msb, olofj
In-Reply-To: <0aa502d0e385f2333f8bc12dafdcde88e5ca0262.1285727642.git.joe@perches.com>
Some miscellaneous typo cleanups.
Add missing newlines to DBG messages.
"debug" is not a good global variable name, use qcusbnet_debug instead.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/usb/qcusbnet/qcusbnet.c | 10 +++++-----
drivers/net/usb/qcusbnet/qmidevice.c | 6 +++---
drivers/net/usb/qcusbnet/structs.h | 2 +-
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/usb/qcusbnet/qcusbnet.c b/drivers/net/usb/qcusbnet/qcusbnet.c
index 54a354e..7e218a8 100644
--- a/drivers/net/usb/qcusbnet/qcusbnet.c
+++ b/drivers/net/usb/qcusbnet/qcusbnet.c
@@ -25,7 +25,7 @@
#define DRIVER_AUTHOR "Qualcomm Innovation Center"
#define DRIVER_DESC "QCUSBNet2k"
-int debug;
+int qcusbnet_debug;
static struct class *devclass;
int qc_suspend(struct usb_interface *iface, pm_message_t event)
@@ -558,7 +558,7 @@ int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids
dev = kmalloc(sizeof(struct qcusbnet), GFP_KERNEL);
if (!dev) {
- DBG("falied to allocate device buffers");
+ DBG("failed to allocate device buffers\n");
return -ENOMEM;
}
@@ -568,7 +568,7 @@ int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids
netdevops = kmalloc(sizeof(struct net_device_ops), GFP_KERNEL);
if (!netdevops) {
- DBG("falied to allocate net device ops");
+ DBG("failed to allocate net device ops\n");
return -ENOMEM;
}
memcpy(netdevops, usbnet->net->netdev_ops, sizeof(struct net_device_ops));
@@ -645,5 +645,5 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("Dual BSD/GPL");
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debuging enabled or not");
+module_param(qcusbnet_debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(qcusbnet_debug, "Debugging enabled or not");
diff --git a/drivers/net/usb/qcusbnet/qmidevice.c b/drivers/net/usb/qcusbnet/qmidevice.c
index 5150453..d1cb341 100755
--- a/drivers/net/usb/qcusbnet/qmidevice.c
+++ b/drivers/net/usb/qcusbnet/qmidevice.c
@@ -54,7 +54,7 @@ struct qmihandle {
struct qcusbnet *dev;
};
-extern int debug;
+extern int qcusbnet_debug;
static int qcusbnet2k_fwdelay;
static bool device_valid(struct qcusbnet *dev);
@@ -339,12 +339,12 @@ int qc_startread(struct qcusbnet *dev)
void qc_stopread(struct qcusbnet *dev)
{
if (dev->qmi.readurb) {
- DBG("Killng read URB\n");
+ DBG("Killing read URB\n");
usb_kill_urb(dev->qmi.readurb);
}
if (dev->qmi.inturb) {
- DBG("Killng int URB\n");
+ DBG("Killing int URB\n");
usb_kill_urb(dev->qmi.inturb);
}
diff --git a/drivers/net/usb/qcusbnet/structs.h b/drivers/net/usb/qcusbnet/structs.h
index 2999e62..7a89c5c 100755
--- a/drivers/net/usb/qcusbnet/structs.h
+++ b/drivers/net/usb/qcusbnet/structs.h
@@ -33,7 +33,7 @@
#define DBG(fmt, arg...) \
do { \
- if (debug == 1) \
+ if (qcusbnet_debug == 1) \
printk(KERN_INFO "QCUSBNet2k::%s " fmt, __func__, ##arg); \
} while (0)
^ permalink raw reply related
* [PATCH net-next] arp: remove unnecessary export of arp_broken_ops
From: Stephen Hemminger @ 2010-09-29 3:08 UTC (permalink / raw)
To: David Miller; +Cc: netdev
arp_broken_ops is only used in arp.c
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/include/net/arp.h 2010-09-29 10:36:46.125871462 +0900
+++ b/include/net/arp.h 2010-09-29 10:36:51.195923872 +0900
@@ -26,6 +26,4 @@ extern struct sk_buff *arp_create(int ty
const unsigned char *target_hw);
extern void arp_xmit(struct sk_buff *skb);
-extern const struct neigh_ops arp_broken_ops;
-
#endif /* _ARP_H */
--- a/net/ipv4/arp.c 2010-09-29 10:36:46.135874409 +0900
+++ b/net/ipv4/arp.c 2010-09-29 10:37:15.985915408 +0900
@@ -161,7 +161,7 @@ static const struct neigh_ops arp_direct
.queue_xmit = dev_queue_xmit,
};
-const struct neigh_ops arp_broken_ops = {
+static const struct neigh_ops arp_broken_ops = {
.family = AF_INET,
.solicit = arp_solicit,
.error_report = arp_error_report,
@@ -170,7 +170,6 @@ const struct neigh_ops arp_broken_ops =
.hh_output = dev_queue_xmit,
.queue_xmit = dev_queue_xmit,
};
-EXPORT_SYMBOL(arp_broken_ops);
struct neigh_table arp_tbl = {
.family = AF_INET,
^ permalink raw reply
* Re: WiMAX linux firmware pull request
From: David Woodhouse @ 2010-09-29 2:52 UTC (permalink / raw)
To: Inaky Perez-Gonzalez; +Cc: wimax, netdev
In-Reply-To: <1285699570.3136.307.camel@localhost.localdomain>
On Tue, 2010-09-28 at 11:46 -0700, Inaky Perez-Gonzalez wrote:
> The 1.3 version is purged as it is not supported anymore.
Not supported by newer kernels? Or "if you are using something that
requires the 1.3 firmware, you can just fuck off and die", along the
lines of what we say to users of the 2.4 kernel?
We shouldn't drop stuff from linux-firmware.git until there really is
*no* reason to need it any more. We shouldn't force people to keep
linux-firmware in step with their kernel; they should always be able to
use the latest.
When I get home from Tokyo I'll be working on a way to specify min/max
kernel versions for each firmware image, along with a 'make install'
target which lets you say "drop anything which is only relevant to
kernels < 2.6.35' or whatever.
--
dwmw2
^ permalink raw reply
* [PATCH 2/2] drivers/net/usb/qcusbnet/qmidevice: Remove printhex, use print_hex_dump
From: Joe Perches @ 2010-09-29 2:39 UTC (permalink / raw)
To: Elly Jones; +Cc: netdev, dbrownell, mjg59, jglasgow, msb, olofj
In-Reply-To: <cover.1285727642.git.joe@perches.com>
Just use the normal kernel facility.
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/usb/qcusbnet/qmidevice.c | 34 ++++++++--------------------------
drivers/net/usb/qcusbnet/qmidevice.h | 1 -
2 files changed, 8 insertions(+), 27 deletions(-)
diff --git a/drivers/net/usb/qcusbnet/qmidevice.c b/drivers/net/usb/qcusbnet/qmidevice.c
index da7e42d..5150453 100755
--- a/drivers/net/usb/qcusbnet/qmidevice.c
+++ b/drivers/net/usb/qcusbnet/qmidevice.c
@@ -113,29 +113,6 @@ static bool device_valid(struct qcusbnet *dev)
return dev && dev->valid;
}
-void printhex(const void *data, size_t size)
-{
- const u8 *cdata = data;
- char *buf;
- size_t pos;
-
- buf = kmalloc(size * 3 + 1, GFP_ATOMIC);
- if (!buf) {
- DBG("Unable to allocate buffer\n");
- return;
- }
-
- memset(buf, 0 , size * 3 + 1);
-
- for (pos = 0; pos < size; pos++) {
- snprintf(buf + (pos * 3), 4, "%02X ", cdata[pos]);
- }
-
- DBG(" : %s\n", buf);
-
- kfree(buf);
-}
-
void qc_setdown(struct qcusbnet *dev, u8 reason)
{
set_bit(reason, &dev->down);
@@ -188,7 +165,8 @@ static void read_callback(struct urb *urb)
data = urb->transfer_buffer;
size = urb->actual_length;
- printhex(data, size);
+ print_hex_dump(KERN_INFO, "QCUSBNet2k: ", DUMP_PREFIX_OFFSET,
+ 16, 1, data, size, true);
result = qmux_parse(&cid, data, size);
if (result < 0) {
@@ -276,7 +254,10 @@ static void int_callback(struct urb *urb)
}
} else {
DBG("ignoring invalid interrupt in packet\n");
- printhex(urb->transfer_buffer, urb->actual_length);
+ print_hex_dump(KERN_INFO, "QCUSBNet2k: ",
+ DUMP_PREFIX_OFFSET, 16, 1,
+ urb->transfer_buffer,
+ urb->actual_length, true);
}
}
@@ -541,7 +522,8 @@ static int write_sync(struct qcusbnet *dev, char *buf, int size, u16 cid)
NULL, dev);
DBG("Actual Write:\n");
- printhex(buf, size);
+ print_hex_dump(KERN_INFO, "QCUSBNet2k: ", DUMP_PREFIX_OFFSET,
+ 16, 1, buf, size, true);
sema_init(&sem, 0);
diff --git a/drivers/net/usb/qcusbnet/qmidevice.h b/drivers/net/usb/qcusbnet/qmidevice.h
index 39a4b7f..5274a0d 100755
--- a/drivers/net/usb/qcusbnet/qmidevice.h
+++ b/drivers/net/usb/qcusbnet/qmidevice.h
@@ -22,7 +22,6 @@
#include "structs.h"
#include "qmi.h"
-void printhex(const void *data, size_t size);
void qc_setdown(struct qcusbnet *dev, u8 reason);
void qc_cleardown(struct qcusbnet *dev, u8 reason);
bool qc_isdown(struct qcusbnet *dev, u8 reason);
--
1.7.3.1.g432b3.dirty
^ permalink raw reply related
* [PATCH 1/2] drivers/net/usb/qcusbnet: Checkpatch cleanups
From: Joe Perches @ 2010-09-29 2:39 UTC (permalink / raw)
To: Elly Jones; +Cc: netdev, dbrownell, mjg59, jglasgow, msb, olofj
In-Reply-To: <cover.1285727642.git.joe@perches.com>
Whitespace and removal of KERNEL_VERSION tests
Neaten DBG macro
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/usb/qcusbnet/qcusbnet.c | 201 ++++++-----------
drivers/net/usb/qcusbnet/qmi.c | 32 ++--
drivers/net/usb/qcusbnet/qmidevice.c | 421 ++++++++++++++++-----------------
drivers/net/usb/qcusbnet/structs.h | 25 +--
4 files changed, 301 insertions(+), 378 deletions(-)
diff --git a/drivers/net/usb/qcusbnet/qcusbnet.c b/drivers/net/usb/qcusbnet/qcusbnet.c
index a075b55..54a354e 100644
--- a/drivers/net/usb/qcusbnet/qcusbnet.c
+++ b/drivers/net/usb/qcusbnet/qcusbnet.c
@@ -30,42 +30,33 @@ static struct class *devclass;
int qc_suspend(struct usb_interface *iface, pm_message_t event)
{
- struct usbnet * usbnet;
- struct qcusbnet * dev;
-
+ struct usbnet *usbnet;
+ struct qcusbnet *dev;
+
if (!iface)
return -ENOMEM;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
+
usbnet = usb_get_intfdata(iface);
-#else
- usbnet = iface->dev.platform_data;
-#endif
if (!usbnet || !usbnet->net) {
DBG("failed to get netdevice\n");
return -ENXIO;
}
-
+
dev = (struct qcusbnet *)usbnet->data[0];
if (!dev) {
DBG("failed to get QMIDevice\n");
return -ENXIO;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- if (!usbnet->udev->auto_pm)
-#else
- if (!(event.event & PM_EVENT_AUTO))
-#endif
- {
- DBG("device suspended to power level %d\n",
- event.event);
+ if (!(event.event & PM_EVENT_AUTO)) {
+ DBG("device suspended to power level %d\n",
+ event.event);
qc_setdown(dev, DOWN_DRIVER_SUSPENDED);
} else {
DBG("device autosuspend\n");
}
-
+
if (event.event & PM_EVENT_SUSPEND) {
qc_stopread(dev);
usbnet->udev->reset_resume = 0;
@@ -73,31 +64,27 @@ int qc_suspend(struct usb_interface *iface, pm_message_t event)
} else {
usbnet->udev->reset_resume = 1;
}
-
+
return usbnet_suspend(iface, event);
}
-static int qc_resume(struct usb_interface * iface)
+static int qc_resume(struct usb_interface *iface)
{
struct usbnet *usbnet;
struct qcusbnet *dev;
int ret;
int oldstate;
-
+
if (iface == 0)
return -ENOMEM;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
+
usbnet = usb_get_intfdata(iface);
-#else
- usbnet = iface->dev.platform_data;
-#endif
if (!usbnet || !usbnet->net) {
DBG("failed to get netdevice\n");
return -ENXIO;
}
-
+
dev = (struct qcusbnet *)usbnet->data[0];
if (!dev) {
DBG("failed to get QMIDevice\n");
@@ -110,7 +97,7 @@ static int qc_resume(struct usb_interface * iface)
if (oldstate & PM_EVENT_SUSPEND) {
qc_cleardown(dev, DOWN_DRIVER_SUSPENDED);
-
+
ret = usbnet_resume(iface);
if (ret) {
DBG("usbnet_resume error %d\n", ret);
@@ -128,7 +115,7 @@ static int qc_resume(struct usb_interface * iface)
DBG("nothing to resume\n");
return 0;
}
-
+
return ret;
}
@@ -139,18 +126,18 @@ static int qcnet_bind(struct usbnet *usbnet, struct usb_interface *iface)
struct usb_host_endpoint *endpoint = NULL;
struct usb_host_endpoint *in = NULL;
struct usb_host_endpoint *out = NULL;
-
+
if (iface->num_altsetting != 1) {
DBG("invalid num_altsetting %u\n", iface->num_altsetting);
return -EINVAL;
}
if (iface->cur_altsetting->desc.bInterfaceNumber != 0) {
- DBG("invalid interface %d\n",
+ DBG("invalid interface %d\n",
iface->cur_altsetting->desc.bInterfaceNumber);
return -EINVAL;
}
-
+
numends = iface->cur_altsetting->desc.bNumEndpoints;
for (i = 0; i < numends; i++) {
endpoint = iface->cur_altsetting->endpoint + i;
@@ -158,7 +145,7 @@ static int qcnet_bind(struct usbnet *usbnet, struct usb_interface *iface)
DBG("invalid endpoint %u\n", i);
return -EINVAL;
}
-
+
if (usb_endpoint_dir_in(&endpoint->desc)
&& !usb_endpoint_xfer_int(&endpoint->desc)) {
in = endpoint;
@@ -166,14 +153,14 @@ static int qcnet_bind(struct usbnet *usbnet, struct usb_interface *iface)
out = endpoint;
}
}
-
+
if (!in || !out) {
DBG("invalid endpoints\n");
return -EINVAL;
}
if (usb_set_interface(usbnet->udev,
- iface->cur_altsetting->desc.bInterfaceNumber, 0)) {
+ iface->cur_altsetting->desc.bInterfaceNumber, 0)) {
DBG("unable to set interface\n");
return -EINVAL;
}
@@ -182,12 +169,9 @@ static int qcnet_bind(struct usbnet *usbnet, struct usb_interface *iface)
usbnet->out = usb_sndbulkpipe(usbnet->udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
DBG("in %x, out %x\n",
- in->desc.bEndpointAddress,
+ in->desc.bEndpointAddress,
out->desc.bEndpointAddress);
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
- iface->dev.platform_data = usbnet;
-#endif
return 0;
}
@@ -197,23 +181,17 @@ static void qcnet_unbind(struct usbnet *usbnet, struct usb_interface *iface)
netif_carrier_off(usbnet->net);
qc_deregister(dev);
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+
kfree(usbnet->net->netdev_ops);
usbnet->net->netdev_ops = NULL;
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
- iface->dev.platform_data = NULL;
-#endif
kfree(dev);
}
-static void qcnet_urbhook(struct urb * urb)
+static void qcnet_urbhook(struct urb *urb)
{
unsigned long flags;
- struct worker * worker = urb->context;
+ struct worker *worker = urb->context;
if (!worker) {
DBG("bad context\n");
return;
@@ -244,7 +222,7 @@ static void qcnet_txtimeout(struct net_device *netdev)
DBG("failed to get usbnet device\n");
return;
}
-
+
dev = (struct qcusbnet *)usbnet->data[0];
if (!dev) {
DBG("failed to get QMIDevice\n");
@@ -283,7 +261,7 @@ static int qcnet_worker(void *arg)
DBG("passed null pointer\n");
return -EINVAL;
}
-
+
usbdev = interface_to_usbdev(worker->iface);
DBG("traffic thread started\n");
@@ -309,7 +287,7 @@ static int qcnet_worker(void *arg)
break;
}
-
+
spin_lock_irqsave(&worker->active_lock, activeflags);
if (IS_ERR(worker->active) && PTR_ERR(worker->active) == -EAGAIN) {
worker->active = NULL;
@@ -322,7 +300,7 @@ static int qcnet_worker(void *arg)
spin_unlock_irqrestore(&worker->active_lock, activeflags);
continue;
}
-
+
spin_lock_irqsave(&worker->urbs_lock, listflags);
if (list_empty(&worker->urbs)) {
spin_unlock_irqrestore(&worker->urbs_lock, listflags);
@@ -340,22 +318,18 @@ static int qcnet_worker(void *arg)
status = usb_autopm_get_interface(worker->iface);
if (status < 0) {
DBG("unable to autoresume interface: %d\n", status);
- if (status == -EPERM)
- {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- usbdev->auto_pm = 0;
-#endif
+ if (status == -EPERM) {
qc_suspend(worker->iface, PMSG_SUSPEND);
}
spin_lock_irqsave(&worker->urbs_lock, listflags);
list_add(&req->node, &worker->urbs);
spin_unlock_irqrestore(&worker->urbs_lock, listflags);
-
+
spin_lock_irqsave(&worker->active_lock, activeflags);
worker->active = NULL;
spin_unlock_irqrestore(&worker->active_lock, activeflags);
-
+
continue;
}
@@ -369,10 +343,10 @@ static int qcnet_worker(void *arg)
usb_autopm_put_interface(worker->iface);
complete(&worker->work);
}
-
+
kfree(req);
- }
-
+ }
+
DBG("traffic thread exiting\n");
worker->thread = NULL;
return 0;
@@ -386,27 +360,27 @@ static int qcnet_startxmit(struct sk_buff *skb, struct net_device *netdev)
struct urbreq *req;
void *data;
struct usbnet *usbnet = netdev_priv(netdev);
-
+
DBG("\n");
-
+
if (!usbnet || !usbnet->net) {
DBG("failed to get usbnet device\n");
return NETDEV_TX_BUSY;
}
-
+
dev = (struct qcusbnet *)usbnet->data[0];
if (!dev) {
DBG("failed to get QMIDevice\n");
return NETDEV_TX_BUSY;
}
worker = &dev->worker;
-
+
if (qc_isdown(dev, DOWN_DRIVER_SUSPENDED)) {
DBG("device is suspended\n");
dump_stack();
return NETDEV_TX_BUSY;
}
-
+
req = kmalloc(sizeof(*req), GFP_ATOMIC);
if (!req) {
DBG("unable to allocate URBList memory\n");
@@ -431,8 +405,8 @@ static int qcnet_startxmit(struct sk_buff *skb, struct net_device *netdev)
memcpy(data, skb->data, skb->len);
usb_fill_bulk_urb(req->urb, dev->usbnet->udev, dev->usbnet->out,
- data, skb->len, qcnet_urbhook, worker);
-
+ data, skb->len, qcnet_urbhook, worker);
+
spin_lock_irqsave(&worker->urbs_lock, listflags);
list_add_tail(&req->node, &worker->urbs);
spin_unlock_irqrestore(&worker->urbs_lock, listflags);
@@ -450,12 +424,12 @@ static int qcnet_open(struct net_device *netdev)
int status = 0;
struct qcusbnet *dev;
struct usbnet *usbnet = netdev_priv(netdev);
-
+
if (!usbnet) {
DBG("failed to get usbnet device\n");
return -ENXIO;
}
-
+
dev = (struct qcusbnet *)usbnet->data[0];
if (!dev) {
DBG("failed to get QMIDevice\n");
@@ -470,30 +444,23 @@ static int qcnet_open(struct net_device *netdev)
spin_lock_init(&dev->worker.urbs_lock);
spin_lock_init(&dev->worker.active_lock);
init_completion(&dev->worker.work);
-
+
dev->worker.thread = kthread_run(qcnet_worker, &dev->worker, "qcnet_worker");
- if (IS_ERR(dev->worker.thread))
- {
+ if (IS_ERR(dev->worker.thread)) {
DBG("AutoPM thread creation error\n");
return PTR_ERR(dev->worker.thread);
}
qc_cleardown(dev, DOWN_NET_IFACE_STOPPED);
- if (dev->open)
- {
+ if (dev->open) {
status = dev->open(netdev);
- if (status == 0)
- {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- usb_autopm_enable(dev->iface);
-#else
+ if (status == 0) {
usb_autopm_put_interface(dev->iface);
-#endif
}
} else {
DBG("no USBNetOpen defined\n");
}
-
+
return status;
}
@@ -506,7 +473,7 @@ int qcnet_stop(struct net_device *netdev)
DBG("failed to get netdevice\n");
return -ENXIO;
}
-
+
dev = (struct qcusbnet *)usbnet->data[0];
if (!dev) {
DBG("failed to get QMIDevice\n");
@@ -523,23 +490,21 @@ int qcnet_stop(struct net_device *netdev)
return 0;
}
-static const struct driver_info qc_netinfo =
-{
- .description = "QCUSBNet Ethernet Device",
- .flags = FLAG_ETHER,
- .bind = qcnet_bind,
- .unbind = qcnet_unbind,
- .data = 0,
+static const struct driver_info qc_netinfo = {
+ .description = "QCUSBNet Ethernet Device",
+ .flags = FLAG_ETHER,
+ .bind = qcnet_bind,
+ .unbind = qcnet_unbind,
+ .data = 0,
};
-#define MKVIDPID(v,p) \
- { \
- USB_DEVICE(v,p), \
- .driver_info = (unsigned long)&qc_netinfo, \
- }
+#define MKVIDPID(v, p) \
+{ \
+ USB_DEVICE(v, p), \
+ .driver_info = (unsigned long)&qc_netinfo, \
+}
-static const struct usb_device_id qc_vidpids [] =
-{
+static const struct usb_device_id qc_vidpids[] = {
MKVIDPID(0x05c6, 0x9215), /* Acer Gobi 2000 */
MKVIDPID(0x05c6, 0x9265), /* Asus Gobi 2000 */
MKVIDPID(0x16d8, 0x8002), /* CMOTech Gobi 2000 */
@@ -556,7 +521,7 @@ static const struct usb_device_id qc_vidpids [] =
MKVIDPID(0x1199, 0x9001), /* Sierra Wireless Gobi 2000 */
MKVIDPID(0x1199, 0x9002), /* Sierra Wireless Gobi 2000 */
MKVIDPID(0x1199, 0x9003), /* Sierra Wireless Gobi 2000 */
- MKVIDPID(0x1199, 0x9004), /* Sierra Wireless Gobi 2000 */
+ MKVIDPID(0x1199, 0x9004), /* Sierra Wireless Gobi 2000 */
MKVIDPID(0x1199, 0x9005), /* Sierra Wireless Gobi 2000 */
MKVIDPID(0x1199, 0x9006), /* Sierra Wireless Gobi 2000 */
MKVIDPID(0x1199, 0x9007), /* Sierra Wireless Gobi 2000 */
@@ -576,9 +541,7 @@ int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids
int status;
struct usbnet *usbnet;
struct qcusbnet *dev;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
struct net_device_ops *netdevops;
-#endif
status = usbnet_probe(iface, vidpids);
if (status < 0) {
@@ -586,11 +549,7 @@ int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids
return status;
}
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
usbnet = usb_get_intfdata(iface);
-#else
- usbnet = iface->dev.platform_data;
-#endif
if (!usbnet || !usbnet->net) {
DBG("failed to get netdevice\n");
@@ -602,26 +561,18 @@ int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids
DBG("falied to allocate device buffers");
return -ENOMEM;
}
-
+
usbnet->data[0] = (unsigned long)dev;
-
+
dev->usbnet = usbnet;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
- dev->open = usbnet->net->open;
- usbnet->net->open = qcnet_open;
- dev->stop = usbnet->net->stop;
- usbnet->net->stop = qcnet_stop;
- usbnet->net->hard_start_xmit = qcnet_startxmit;
- usbnet->net->tx_timeout = qcnet_txtimeout;
-#else
netdevops = kmalloc(sizeof(struct net_device_ops), GFP_KERNEL);
if (!netdevops) {
DBG("falied to allocate net device ops");
return -ENOMEM;
}
memcpy(netdevops, usbnet->net->netdev_ops, sizeof(struct net_device_ops));
-
+
dev->open = netdevops->ndo_open;
netdevops->ndo_open = qcnet_open;
dev->stop = netdevops->ndo_stop;
@@ -630,25 +581,19 @@ int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids
netdevops->ndo_tx_timeout = qcnet_txtimeout;
usbnet->net->netdev_ops = netdevops;
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
- memset(&(dev->usbnet->stats), 0, sizeof(struct net_device_stats));
-#else
memset(&(dev->usbnet->net->stats), 0, sizeof(struct net_device_stats));
-#endif
dev->iface = iface;
memset(&(dev->meid), '0', 14);
-
- DBG("Mac Address:\n");
- printhex(&dev->usbnet->net->dev_addr[0], 6);
+
+ DBG("Mac Address: %pM\n", dev->usbnet->net->dev_addr);
dev->valid = false;
memset(&dev->qmi, 0, sizeof(struct qmidev));
dev->qmi.devclass = devclass;
-
+
INIT_LIST_HEAD(&dev->qmi.clients);
init_completion(&dev->worker.work);
spin_lock_init(&dev->qmi.clients_lock);
@@ -661,14 +606,12 @@ int qcnet_probe(struct usb_interface *iface, const struct usb_device_id *vidpids
if (status) {
qc_deregister(dev);
}
-
+
return status;
}
-
EXPORT_SYMBOL_GPL(qcnet_probe);
-static struct usb_driver qcusbnet =
-{
+static struct usb_driver qcusbnet = {
.name = "QCUSBNet2k",
.id_table = qc_vidpids,
.probe = qcnet_probe,
diff --git a/drivers/net/usb/qcusbnet/qmi.c b/drivers/net/usb/qcusbnet/qmi.c
index 2fc8ce8..cdbdbaf 100755
--- a/drivers/net/usb/qcusbnet/qmi.c
+++ b/drivers/net/usb/qcusbnet/qmi.c
@@ -177,7 +177,7 @@ void *qmidms_new_getmeid(u8 tid, size_t *size)
int qmux_parse(u16 *cid, void *buf, size_t size)
{
struct qmux *qmux = buf;
-
+
if (!buf || size < 12)
return -ENOMEM;
@@ -203,13 +203,14 @@ int qmux_fill(u16 cid, void *buf, size_t size)
return 0;
}
-static u16 tlv_get(void *msg, u16 msgsize, u8 type, void *buf, u16 bufsize) {
+static u16 tlv_get(void *msg, u16 msgsize, u8 type, void *buf, u16 bufsize)
+{
u16 pos;
u16 msize = 0;
-
+
if (!msg || !buf)
return -ENOMEM;
-
+
for (pos = 4; pos + 3 < msgsize; pos += msize + 3) {
msize = *(u16 *)(msg + pos + 1);
if (*(u8 *)(msg + pos) == type) {
@@ -220,7 +221,7 @@ static u16 tlv_get(void *msg, u16 msgsize, u8 type, void *buf, u16 bufsize) {
return msize;
}
}
-
+
return -ENOMSG;
}
@@ -305,21 +306,21 @@ int qmiwds_event_resp(void *buf, u16 size, struct qmiwds_stats *stats)
result = qmi_msgid(buf, size);
if (result == 0x01) {
- tlv_get(buf, size, 0x10, (void*)&stats->txok, 4);
- tlv_get(buf, size, 0x11, (void*)&stats->rxok, 4);
- tlv_get(buf, size, 0x12, (void*)&stats->txerr, 4);
- tlv_get(buf, size, 0x13, (void*)&stats->rxerr, 4);
- tlv_get(buf, size, 0x14, (void*)&stats->txofl, 4);
- tlv_get(buf, size, 0x15, (void*)&stats->rxofl, 4);
- tlv_get(buf, size, 0x19, (void*)&stats->txbytesok, 8);
- tlv_get(buf, size, 0x1A, (void*)&stats->rxbytesok, 8);
+ tlv_get(buf, size, 0x10, &stats->txok, 4);
+ tlv_get(buf, size, 0x11, &stats->rxok, 4);
+ tlv_get(buf, size, 0x12, &stats->txerr, 4);
+ tlv_get(buf, size, 0x13, &stats->rxerr, 4);
+ tlv_get(buf, size, 0x14, &stats->txofl, 4);
+ tlv_get(buf, size, 0x15, &stats->rxofl, 4);
+ tlv_get(buf, size, 0x19, &stats->txbytesok, 8);
+ tlv_get(buf, size, 0x1A, &stats->rxbytesok, 8);
} else if (result == 0x22) {
result = tlv_get(buf, size, 0x01, &status[0], 2);
if (result >= 1)
stats->linkstate = status[0] == 0x02;
if (result == 2)
stats->reconfigure = status[1] == 0x01;
-
+
if (result < 0)
return result;
} else {
@@ -349,10 +350,9 @@ int qmidms_meid_resp(void *buf, u16 size, char *meid, int meidsize)
if (result)
return -EFAULT;
- result = tlv_get(buf, size, 0x12, (void*)meid, 14);
+ result = tlv_get(buf, size, 0x12, meid, 14);
if (result != 14)
return -EFAULT;
return 0;
}
-
diff --git a/drivers/net/usb/qcusbnet/qmidevice.c b/drivers/net/usb/qcusbnet/qmidevice.c
index b5006be..da7e42d 100755
--- a/drivers/net/usb/qcusbnet/qmidevice.c
+++ b/drivers/net/usb/qcusbnet/qmidevice.c
@@ -28,7 +28,7 @@ struct readreq {
struct notifyreq {
struct list_head node;
- void (* func)(struct qcusbnet *, u16, void *);
+ void (*func)(struct qcusbnet *, u16, void *);
u16 tid;
void *data;
};
@@ -55,15 +55,15 @@ struct qmihandle {
};
extern int debug;
-static int qcusbnet2k_fwdelay = 0;
+static int qcusbnet2k_fwdelay;
static bool device_valid(struct qcusbnet *dev);
static struct client *client_bycid(struct qcusbnet *dev, u16 cid);
static bool client_addread(struct qcusbnet *dev, u16 cid, u16 tid, void *data, u16 size);
static bool client_delread(struct qcusbnet *dev, u16 cid, u16 tid, void **data, u16 *size);
static bool client_addnotify(struct qcusbnet *dev, u16 cid, u16 tid,
- void (*hook)(struct qcusbnet *, u16 cid, void *),
- void *data);
+ void (*hook)(struct qcusbnet *, u16 cid, void *),
+ void *data);
static bool client_notify(struct qcusbnet *dev, u16 cid, u16 tid);
static bool client_addurb(struct qcusbnet *dev, u16 cid, struct urb *urb);
static struct urb *client_delurb(struct qcusbnet *dev, u16 cid);
@@ -72,23 +72,22 @@ static int devqmi_open(struct inode *inode, struct file *file);
static long devqmi_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static int devqmi_close(struct file *file, fl_owner_t ftable);
static ssize_t devqmi_read(struct file *file, char __user *buf, size_t size,
- loff_t *pos);
+ loff_t *pos);
static ssize_t devqmi_write(struct file *file, const char __user *buf,
- size_t size, loff_t *pos);
+ size_t size, loff_t *pos);
static bool qmi_ready(struct qcusbnet *dev, u16 timeout);
static void wds_callback(struct qcusbnet *dev, u16 cid, void *data);
static int setup_wds_callback(struct qcusbnet *dev);
static int qmidms_getmeid(struct qcusbnet *dev);
-#define IOCTL_QMI_GET_SERVICE_FILE 0x8BE0 + 1
-#define IOCTL_QMI_GET_DEVICE_VIDPID 0x8BE0 + 2
-#define IOCTL_QMI_GET_DEVICE_MEID 0x8BE0 + 3
-#define CDC_GET_ENCAPSULATED_RESPONSE 0x01A1ll
-#define CDC_CONNECTION_SPEED_CHANGE 0x08000000002AA1ll
+#define IOCTL_QMI_GET_SERVICE_FILE (0x8BE0 + 1)
+#define IOCTL_QMI_GET_DEVICE_VIDPID (0x8BE0 + 2)
+#define IOCTL_QMI_GET_DEVICE_MEID (0x8BE0 + 3)
+#define CDC_GET_ENCAPSULATED_RESPONSE 0x01A1ll
+#define CDC_CONNECTION_SPEED_CHANGE 0x08000000002AA1ll
-struct file_operations devqmi_fops =
-{
+static const struct file_operations devqmi_fops = {
.owner = THIS_MODULE,
.read = devqmi_read,
.write = devqmi_write,
@@ -112,7 +111,7 @@ static inline void assert_locked(struct qcusbnet *dev)
static bool device_valid(struct qcusbnet *dev)
{
return dev && dev->valid;
-}
+}
void printhex(const void *data, size_t size)
{
@@ -132,7 +131,7 @@ void printhex(const void *data, size_t size)
snprintf(buf + (pos * 3), 4, "%02X ", cdata[pos]);
}
- DBG( " : %s\n", buf);
+ DBG(" : %s\n", buf);
kfree(buf);
}
@@ -203,9 +202,9 @@ static void read_callback(struct urb *urb)
}
if (cid == QMICTL)
- tid = *(u8*)(data + result + 1);
+ tid = *(u8 *)(data + result + 1);
else
- tid = *(u16*)(data + result + 1);
+ tid = *(u16 *)(data + result + 1);
spin_lock_irqsave(&dev->qmi.clients_lock, flags);
list_for_each(node, &dev->qmi.clients) {
@@ -230,7 +229,7 @@ static void read_callback(struct urb *urb)
break;
}
}
-
+
spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
}
@@ -250,25 +249,25 @@ static void int_callback(struct urb *urb)
if (urb->status != -EOVERFLOW)
return;
} else {
- if ((urb->actual_length == 8)
- && (*(u64*)urb->transfer_buffer == CDC_GET_ENCAPSULATED_RESPONSE)) {
+ if ((urb->actual_length == 8) &&
+ (*(u64 *)urb->transfer_buffer == CDC_GET_ENCAPSULATED_RESPONSE)) {
usb_fill_control_urb(dev->qmi.readurb, dev->usbnet->udev,
- usb_rcvctrlpipe(dev->usbnet->udev, 0),
- (unsigned char *)dev->qmi.readsetup,
- dev->qmi.readbuf,
- DEFAULT_READ_URB_LENGTH,
- read_callback, dev);
+ usb_rcvctrlpipe(dev->usbnet->udev, 0),
+ (unsigned char *)dev->qmi.readsetup,
+ dev->qmi.readbuf,
+ DEFAULT_READ_URB_LENGTH,
+ read_callback, dev);
status = usb_submit_urb(dev->qmi.readurb, GFP_ATOMIC);
if (status) {
DBG("Error submitting Read URB %d\n", status);
return;
}
- } else if ((urb->actual_length == 16)
- && (*(u64*)urb->transfer_buffer == CDC_CONNECTION_SPEED_CHANGE)) {
+ } else if ((urb->actual_length == 16) &&
+ (*(u64 *)urb->transfer_buffer == CDC_CONNECTION_SPEED_CHANGE)) {
/* if upstream or downstream is 0, stop traffic.
* Otherwise resume it */
- if ((*(u32*)(urb->transfer_buffer + 8) == 0)
- || (*(u32*)(urb->transfer_buffer + 12) == 0)) {
+ if ((*(u32 *)(urb->transfer_buffer + 8) == 0) ||
+ (*(u32 *)(urb->transfer_buffer + 12) == 0)) {
qc_setdown(dev, DOWN_CDC_CONNECTION_SPEED);
DBG("traffic stopping due to CONNECTION_SPEED_CHANGE\n");
} else {
@@ -284,8 +283,8 @@ static void int_callback(struct urb *urb)
interval = (dev->usbnet->udev->speed == USB_SPEED_HIGH) ? 7 : 3;
usb_fill_int_urb(urb, urb->dev, urb->pipe, urb->transfer_buffer,
- urb->transfer_buffer_length, urb->complete,
- urb->context, interval);
+ urb->transfer_buffer_length, urb->complete,
+ urb->context, interval);
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status)
DBG("Error re-submitting Int URB %d\n", status);
@@ -300,13 +299,13 @@ int qc_startread(struct qcusbnet *dev)
DBG("Invalid device!\n");
return -ENXIO;
}
-
+
dev->qmi.readurb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->qmi.readurb) {
DBG("Error allocating read urb\n");
return -ENOMEM;
}
-
+
dev->qmi.inturb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->qmi.inturb) {
usb_free_urb(dev->qmi.readurb);
@@ -321,7 +320,7 @@ int qc_startread(struct qcusbnet *dev)
DBG("Error allocating read buffer\n");
return -ENOMEM;
}
-
+
dev->qmi.intbuf = kmalloc(DEFAULT_READ_URB_LENGTH, GFP_KERNEL);
if (!dev->qmi.intbuf) {
usb_free_urb(dev->qmi.readurb);
@@ -329,8 +328,8 @@ int qc_startread(struct qcusbnet *dev)
kfree(dev->qmi.readbuf);
DBG("Error allocating int buffer\n");
return -ENOMEM;
- }
-
+ }
+
dev->qmi.readsetup = kmalloc(sizeof(*dev->qmi.readsetup), GFP_KERNEL);
if (!dev->qmi.readsetup) {
usb_free_urb(dev->qmi.readurb);
@@ -348,15 +347,15 @@ int qc_startread(struct qcusbnet *dev)
dev->qmi.readsetup->len = DEFAULT_READ_URB_LENGTH;
interval = (dev->usbnet->udev->speed == USB_SPEED_HIGH) ? 7 : 3;
-
+
usb_fill_int_urb(dev->qmi.inturb, dev->usbnet->udev,
- usb_rcvintpipe(dev->usbnet->udev, 0x81),
- dev->qmi.intbuf, DEFAULT_READ_URB_LENGTH,
- int_callback, dev, interval);
+ usb_rcvintpipe(dev->usbnet->udev, 0x81),
+ dev->qmi.intbuf, DEFAULT_READ_URB_LENGTH,
+ int_callback, dev, interval);
return usb_submit_urb(dev->qmi.inturb, GFP_KERNEL);
}
-void qc_stopread(struct qcusbnet * dev)
+void qc_stopread(struct qcusbnet *dev)
{
if (dev->qmi.readurb) {
DBG("Killng read URB\n");
@@ -374,7 +373,7 @@ void qc_stopread(struct qcusbnet * dev)
dev->qmi.readbuf = NULL;
kfree(dev->qmi.intbuf);
dev->qmi.intbuf = NULL;
-
+
usb_free_urb(dev->qmi.readurb);
dev->qmi.readurb = NULL;
usb_free_urb(dev->qmi.inturb);
@@ -382,12 +381,13 @@ void qc_stopread(struct qcusbnet * dev)
}
static int read_async(struct qcusbnet *dev, u16 cid, u16 tid,
- void (*hook)(struct qcusbnet*, u16, void *), void *data)
+ void (*hook)(struct qcusbnet *, u16, void *),
+ void *data)
{
struct list_head *node;
struct client *client;
struct readreq *readreq;
-
+
unsigned long flags;
if (!device_valid(dev)) {
@@ -420,7 +420,7 @@ static int read_async(struct qcusbnet *dev, u16 cid, u16 tid,
return 0;
}
-static void upsem(struct qcusbnet *dev, u16 cid, void *data)
+static void upsem(struct qcusbnet *dev, u16 cid, void *data)
{
DBG("0x%04X\n", cid);
up((struct semaphore *)data);
@@ -430,10 +430,10 @@ static int read_sync(struct qcusbnet *dev, void **buf, u16 cid, u16 tid)
{
struct list_head *node;
int result;
- struct client * client;
+ struct client *client;
struct notifyreq *notify;
struct semaphore sem;
- void * data;
+ void *data;
unsigned long flags;
u16 size;
@@ -441,7 +441,7 @@ static int read_sync(struct qcusbnet *dev, void **buf, u16 cid, u16 tid)
DBG("Invalid device!\n");
return -ENXIO;
}
-
+
spin_lock_irqsave(&dev->qmi.clients_lock, flags);
client = client_bycid(dev, cid);
@@ -450,7 +450,7 @@ static int read_sync(struct qcusbnet *dev, void **buf, u16 cid, u16 tid)
spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
return -ENXIO;
}
-
+
while (!client_delread(dev, cid, tid, &data, &size)) {
sema_init(&sem, 0);
if (!client_addnotify(dev, cid, tid, upsem, &sem)) {
@@ -477,15 +477,15 @@ static int read_sync(struct qcusbnet *dev, void **buf, u16 cid, u16 tid)
spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
return -EINTR;
}
-
+
if (!device_valid(dev)) {
DBG("Invalid device!\n");
return -ENXIO;
}
-
+
spin_lock_irqsave(&dev->qmi.clients_lock, flags);
}
-
+
spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
*buf = data;
return size;
@@ -536,25 +536,22 @@ static int write_sync(struct qcusbnet *dev, char *buf, int size, u16 cid)
setup.len = size;
usb_fill_control_urb(urb, dev->usbnet->udev,
- usb_sndctrlpipe(dev->usbnet->udev, 0),
- (unsigned char *)&setup, (void*)buf, size,
- NULL, dev);
+ usb_sndctrlpipe(dev->usbnet->udev, 0),
+ (unsigned char *)&setup, (void *)buf, size,
+ NULL, dev);
DBG("Actual Write:\n");
printhex(buf, size);
sema_init(&sem, 0);
-
+
urb->complete = write_callback;
urb->context = &sem;
-
+
result = usb_autopm_get_interface(dev->iface);
if (result < 0) {
DBG("unable to resume interface: %d\n", result);
if (result == -EPERM) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
- dev->usbnet->udev->auto_pm = 0;
-#endif
qc_suspend(dev->iface, PMSG_SUSPEND);
}
return result;
@@ -564,7 +561,7 @@ static int write_sync(struct qcusbnet *dev, char *buf, int size, u16 cid)
if (!client_addurb(dev, cid, urb)) {
usb_free_urb(urb);
- spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
+ spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
usb_autopm_put_interface(dev->iface);
return -EINVAL;
}
@@ -582,8 +579,8 @@ static int write_sync(struct qcusbnet *dev, char *buf, int size, u16 cid)
usb_autopm_put_interface(dev->iface);
return result;
}
-
- spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
+
+ spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
result = down_interruptible(&sem);
if (!device_valid(dev)) {
DBG("Invalid device!\n");
@@ -592,13 +589,12 @@ static int write_sync(struct qcusbnet *dev, char *buf, int size, u16 cid)
usb_autopm_put_interface(dev->iface);
spin_lock_irqsave(&dev->qmi.clients_lock, flags);
- if (client_delurb(dev, cid) != urb)
- {
+ if (client_delurb(dev, cid) != urb) {
DBG("Didn't get write URB back\n");
- spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
+ spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
return -EINVAL;
}
- spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
+ spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
if (!result) {
if (!urb->status) {
@@ -622,13 +618,13 @@ static int client_alloc(struct qcusbnet *dev, u8 type)
u16 cid;
struct client *client;
int result;
- void * wbuf;
+ void *wbuf;
size_t wbufsize;
- void * rbuf;
+ void *rbuf;
u16 rbufsize;
unsigned long flags;
u8 tid;
-
+
if (!device_valid(dev)) {
DBG("Invalid device!\n");
return -ENXIO;
@@ -691,12 +687,12 @@ static void client_free(struct qcusbnet *dev, u16 cid)
struct list_head *node, *tmp;
int result;
struct client *client;
- struct urb * urb;
- void * data;
+ struct urb *urb;
+ void *data;
u16 size;
- void * wbuf;
+ void *wbuf;
size_t wbufsize;
- void * rbuf;
+ void *rbuf;
u16 rbufsize;
unsigned long flags;
u8 tid;
@@ -705,11 +701,10 @@ static void client_free(struct qcusbnet *dev, u16 cid)
DBG("invalid device\n");
return;
}
-
+
DBG("releasing 0x%04X\n", cid);
- if (cid != QMICTL)
- {
+ if (cid != QMICTL) {
tid = atomic_add_return(1, &dev->qmi.qmitid);
if (!tid)
tid = atomic_add_return(1, &dev->qmi.qmitid);
@@ -741,7 +736,9 @@ static void client_free(struct qcusbnet *dev, u16 cid)
list_for_each_safe(node, tmp, &dev->qmi.clients) {
client = list_entry(node, struct client, node);
if (client->cid == cid) {
- while (client_notify(dev, cid, 0));
+ while (client_notify(dev, cid, 0)) {
+ ;
+ }
urb = client_delurb(dev, cid);
while (urb != NULL) {
@@ -757,7 +754,7 @@ static void client_free(struct qcusbnet *dev, u16 cid)
kfree(client);
}
}
-
+
spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
}
@@ -765,14 +762,14 @@ struct client *client_bycid(struct qcusbnet *dev, u16 cid)
{
struct list_head *node;
struct client *client;
-
+
if (!device_valid(dev)) {
DBG("Invalid device\n");
return NULL;
}
- assert_locked(dev);
-
+ assert_locked(dev);
+
list_for_each(node, &dev->qmi.clients) {
client = list_entry(node, struct client, node);
if (client->cid == cid)
@@ -784,7 +781,7 @@ struct client *client_bycid(struct qcusbnet *dev, u16 cid)
}
static bool client_addread(struct qcusbnet *dev, u16 cid, u16 tid, void *data,
- u16 size)
+ u16 size)
{
struct client *client;
struct readreq *req;
@@ -808,12 +805,12 @@ static bool client_addread(struct qcusbnet *dev, u16 cid, u16 tid, void *data,
req->tid = tid;
list_add_tail(&req->node, &client->reads);
-
+
return true;
}
static bool client_delread(struct qcusbnet *dev, u16 cid, u16 tid, void **data,
- u16 *size)
+ u16 *size)
{
struct client *client;
struct readreq *req;
@@ -826,7 +823,7 @@ static bool client_delread(struct qcusbnet *dev, u16 cid, u16 tid, void **data,
DBG("Could not find this client's memory 0x%04X\n", cid);
return false;
}
-
+
list_for_each(node, &client->reads) {
req = list_entry(node, struct readreq, node);
if (!tid || tid == req->tid) {
@@ -836,17 +833,17 @@ static bool client_delread(struct qcusbnet *dev, u16 cid, u16 tid, void **data,
kfree(req);
return true;
}
-
+
DBG("skipping 0x%04X data TID = %x\n", cid, req->tid);
}
-
+
DBG("No read memory to pop, Client 0x%04X, TID = %x\n", cid, tid);
return false;
}
static bool client_addnotify(struct qcusbnet *dev, u16 cid, u16 tid,
- void (*hook)(struct qcusbnet *, u16, void *),
- void *data)
+ void (*hook)(struct qcusbnet *, u16, void *),
+ void *data)
{
struct client *client;
struct notifyreq *req;
@@ -895,10 +892,10 @@ static bool client_notify(struct qcusbnet *dev, u16 cid, u16 tid)
delnotify = notify;
break;
}
-
+
DBG("skipping data TID = %x\n", notify->tid);
}
-
+
if (delnotify) {
list_del(&delnotify->node);
if (delnotify->func) {
@@ -910,7 +907,7 @@ static bool client_notify(struct qcusbnet *dev, u16 cid, u16 tid)
return true;
}
- DBG("no one to notify for TID %x\n", tid);
+ DBG("no one to notify for TID %x\n", tid);
return false;
}
@@ -931,11 +928,11 @@ static bool client_addurb(struct qcusbnet *dev, u16 cid, struct urb *urb)
if (!req) {
DBG("Mem error\n");
return false;
- }
+ }
req->urb = urb;
list_add_tail(&req->node, &client->urbs);
-
+
return true;
}
@@ -967,9 +964,9 @@ static struct urb *client_delurb(struct qcusbnet *dev, u16 cid)
static int devqmi_open(struct inode *inode, struct file *file)
{
- struct qmihandle * handle;
+ struct qmihandle *handle;
struct qmidev *qmidev = container_of(inode->i_cdev, struct qmidev, cdev);
- struct qcusbnet * dev = container_of(qmidev, struct qcusbnet, qmi);
+ struct qcusbnet *dev = container_of(qmidev, struct qcusbnet, qmi);
if (!device_valid(dev)) {
DBG("Invalid device\n");
@@ -981,11 +978,11 @@ static int devqmi_open(struct inode *inode, struct file *file)
DBG("Mem error\n");
return -ENOMEM;
}
-
+
handle = (struct qmihandle *)file->private_data;
handle->cid = (u16)-1;
handle->dev = dev;
-
+
return 0;
}
@@ -993,14 +990,14 @@ static long devqmi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int result;
u32 vidpid;
-
+
struct qmihandle *handle = (struct qmihandle *)file->private_data;
if (!handle) {
DBG("Bad file data\n");
return -EBADF;
}
-
+
if (!device_valid(handle->dev)) {
DBG("Invalid device! Updating f_ops\n");
file->f_op = file->f_dentry->d_inode->i_fop;
@@ -1008,77 +1005,77 @@ static long devqmi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
switch (cmd) {
- case IOCTL_QMI_GET_SERVICE_FILE:
+ case IOCTL_QMI_GET_SERVICE_FILE:
- DBG("Setting up QMI for service %lu\n", arg);
- if (!(u8)arg) {
- DBG("Cannot use QMICTL from userspace\n");
- return -EINVAL;
- }
+ DBG("Setting up QMI for service %lu\n", arg);
+ if (!(u8)arg) {
+ DBG("Cannot use QMICTL from userspace\n");
+ return -EINVAL;
+ }
- if (handle->cid != (u16)-1) {
- DBG("Close the current connection before opening a new one\n");
- return -EBADR;
- }
-
- result = client_alloc(handle->dev, (u8)arg);
- if (result < 0)
- return result;
- handle->cid = result;
+ if (handle->cid != (u16)-1) {
+ DBG("Close the current connection before opening a new one\n");
+ return -EBADR;
+ }
- return 0;
- break;
+ result = client_alloc(handle->dev, (u8)arg);
+ if (result < 0)
+ return result;
+ handle->cid = result;
+ return 0;
+ break;
- case IOCTL_QMI_GET_DEVICE_VIDPID:
- if (!arg) {
- DBG("Bad VIDPID buffer\n");
- return -EINVAL;
- }
-
- if (!handle->dev->usbnet) {
- DBG("Bad usbnet\n");
- return -ENOMEM;
- }
- if (!handle->dev->usbnet->udev) {
- DBG("Bad udev\n");
- return -ENOMEM;
- }
+ case IOCTL_QMI_GET_DEVICE_VIDPID:
+ if (!arg) {
+ DBG("Bad VIDPID buffer\n");
+ return -EINVAL;
+ }
- vidpid = ((le16_to_cpu(handle->dev->usbnet->udev->descriptor.idVendor) << 16)
- + le16_to_cpu(handle->dev->usbnet->udev->descriptor.idProduct));
+ if (!handle->dev->usbnet) {
+ DBG("Bad usbnet\n");
+ return -ENOMEM;
+ }
- result = copy_to_user((unsigned int *)arg, &vidpid, 4);
- if (result)
- DBG("Copy to userspace failure\n");
+ if (!handle->dev->usbnet->udev) {
+ DBG("Bad udev\n");
+ return -ENOMEM;
+ }
- return result;
- break;
+ vidpid = ((le16_to_cpu(handle->dev->usbnet->udev->descriptor.idVendor) << 16)
+ + le16_to_cpu(handle->dev->usbnet->udev->descriptor.idProduct));
- case IOCTL_QMI_GET_DEVICE_MEID:
- if (!arg) {
- DBG("Bad MEID buffer\n");
- return -EINVAL;
- }
-
- result = copy_to_user((unsigned int *)arg, &handle->dev->meid[0], 14);
- if (result)
- DBG("copy to userspace failure\n");
+ result = copy_to_user((unsigned int *)arg, &vidpid, 4);
+ if (result)
+ DBG("Copy to userspace failure\n");
- return result;
- break;
- default:
- return -EBADRQC;
+ return result;
+ break;
+
+ case IOCTL_QMI_GET_DEVICE_MEID:
+ if (!arg) {
+ DBG("Bad MEID buffer\n");
+ return -EINVAL;
+ }
+
+ result = copy_to_user((unsigned int *)arg, &handle->dev->meid[0], 14);
+ if (result)
+ DBG("copy to userspace failure\n");
+
+ return result;
+ break;
+ default:
+ return -EBADRQC;
}
}
static int devqmi_close(struct file *file, fl_owner_t ftable)
{
- struct qmihandle * handle = (struct qmihandle *)file->private_data;
- struct list_head * tasks;
- struct task_struct * task;
- struct fdtable * fdtable;
+ struct qmihandle *handle = (struct qmihandle *)file->private_data;
+ struct list_head *tasks;
+ struct task_struct *task;
+ struct fdtable *fdtable;
int count = 0;
int used = 0;
unsigned long flags;
@@ -1109,7 +1106,7 @@ static int devqmi_close(struct file *file, fl_owner_t ftable)
}
spin_unlock_irqrestore(&task->files->file_lock, flags);
}
-
+
if (used > 0) {
DBG("not closing, as this FD is open by %d other process\n", used);
return 0;
@@ -1121,9 +1118,9 @@ static int devqmi_close(struct file *file, fl_owner_t ftable)
file->f_op = file->f_dentry->d_inode->i_fop;
return -ENXIO;
}
-
+
DBG("0x%04X\n", handle->cid);
-
+
file->private_data = NULL;
if (handle->cid != (u16)-1)
@@ -1134,12 +1131,12 @@ static int devqmi_close(struct file *file, fl_owner_t ftable)
}
static ssize_t devqmi_read(struct file *file, char __user *buf, size_t size,
- loff_t *pos)
+ loff_t *pos)
{
int result;
- void * data = NULL;
- void * smalldata;
- struct qmihandle * handle = (struct qmihandle *)file->private_data;
+ void *data = NULL;
+ void *smalldata;
+ struct qmihandle *handle = (struct qmihandle *)file->private_data;
if (!handle) {
DBG("Bad file data\n");
@@ -1151,17 +1148,17 @@ static ssize_t devqmi_read(struct file *file, char __user *buf, size_t size,
file->f_op = file->f_dentry->d_inode->i_fop;
return -ENXIO;
}
-
+
if (handle->cid == (u16)-1) {
DBG("Client ID must be set before reading 0x%04X\n",
handle->cid);
return -EBADR;
}
-
+
result = read_sync(handle->dev, &data, handle->cid, 0);
if (result <= 0)
return result;
-
+
result -= qmux_size;
smalldata = data + qmux_size;
@@ -1175,13 +1172,13 @@ static ssize_t devqmi_read(struct file *file, char __user *buf, size_t size,
DBG("Error copying read data to user\n");
result = -EFAULT;
}
-
+
kfree(data);
return result;
}
-static ssize_t devqmi_write (struct file *file, const char __user * buf,
- size_t size, loff_t *pos)
+static ssize_t devqmi_write(struct file *file, const char __user * buf,
+ size_t size, loff_t *pos)
{
int status;
void *wbuf;
@@ -1203,7 +1200,7 @@ static ssize_t devqmi_write (struct file *file, const char __user * buf,
handle->cid);
return -EBADR;
}
-
+
wbuf = kmalloc(size + qmux_size, GFP_KERNEL);
if (!wbuf)
return -ENOMEM;
@@ -1215,7 +1212,7 @@ static ssize_t devqmi_write (struct file *file, const char __user * buf,
}
status = write_sync(handle->dev, wbuf, size + qmux_size,
- handle->cid);
+ handle->cid);
kfree(wbuf);
if (status == size + qmux_size)
@@ -1227,9 +1224,9 @@ int qc_register(struct qcusbnet *dev)
{
int result;
int qmiidx = 0;
- dev_t devno;
- char * name;
-
+ dev_t devno;
+ char *name;
+
dev->valid = true;
result = client_alloc(dev, QMICTL);
if (result) {
@@ -1243,7 +1240,7 @@ int qc_register(struct qcusbnet *dev)
dev->valid = false;
return result;
}
-
+
if (!qmi_ready(dev, 30000)) {
DBG("Device unresponsive to QMI\n");
return -ETIMEDOUT;
@@ -1288,12 +1285,8 @@ int qc_register(struct qcusbnet *dev)
}
printk(KERN_INFO "creating qcqmi%d\n", qmiidx);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
device_create(dev->qmi.devclass, NULL, devno, NULL, "qcqmi%d", qmiidx);
-#else
- device_create(dev->qmi.devclass, NULL, devno, "qcqmi%d", qmiidx);
-#endif
-
+
dev->qmi.devnum = devno;
return 0;
}
@@ -1302,12 +1295,12 @@ void qc_deregister(struct qcusbnet *dev)
{
struct list_head *node;
struct client *client;
- struct inode * inode;
- struct list_head * inodes;
- struct list_head * tasks;
- struct task_struct * task;
- struct fdtable * fdtable;
- struct file * file;
+ struct inode *inode;
+ struct list_head *inodes;
+ struct list_head *tasks;
+ struct task_struct *task;
+ struct fdtable *fdtable;
+ struct file *file;
unsigned long flags;
int count = 0;
@@ -1337,7 +1330,7 @@ void qc_deregister(struct qcusbnet *dev)
file = fdtable->fd[count];
if (file != NULL && file->f_dentry != NULL) {
if (file->f_dentry->d_inode == inode) {
- rcu_assign_pointer(fdtable->fd[count], NULL);
+ rcu_assign_pointer(fdtable->fd[count], NULL);
spin_unlock_irqrestore(&task->files->file_lock, flags);
DBG("forcing close of open file handle\n");
filp_close(file, task->files);
@@ -1359,15 +1352,15 @@ void qc_deregister(struct qcusbnet *dev)
static bool qmi_ready(struct qcusbnet *dev, u16 timeout)
{
int result;
- void * wbuf;
+ void *wbuf;
size_t wbufsize;
- void * rbuf;
+ void *rbuf;
u16 rbufsize;
struct semaphore sem;
u16 now;
unsigned long flags;
u8 tid;
-
+
if (!device_valid(dev)) {
DBG("Invalid device\n");
return -EFAULT;
@@ -1380,12 +1373,11 @@ static bool qmi_ready(struct qcusbnet *dev, u16 timeout)
tid = atomic_add_return(1, &dev->qmi.qmitid);
if (!tid)
tid = atomic_add_return(1, &dev->qmi.qmitid);
- if (wbuf)
- kfree(wbuf);
+ kfree(wbuf);
wbuf = qmictl_new_ready(tid, &wbufsize);
if (!wbuf)
return -ENOMEM;
-
+
result = read_async(dev, QMICTL, tid, upsem, &sem);
if (result) {
kfree(wbuf);
@@ -1409,12 +1401,11 @@ static bool qmi_ready(struct qcusbnet *dev, u16 timeout)
}
}
- if (wbuf)
- kfree(wbuf);
+ kfree(wbuf);
if (now >= timeout)
return false;
-
+
DBG("QMI Ready after %u milliseconds\n", now);
/* 3580 and newer doesn't need a delay; older needs 5000ms */
@@ -1428,14 +1419,10 @@ static void wds_callback(struct qcusbnet *dev, u16 cid, void *data)
{
bool ret;
int result;
- void * rbuf;
+ void *rbuf;
u16 rbufsize;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
- struct net_device_stats * stats = &(dev->usbnet->stats);
-#else
- struct net_device_stats * stats = &(dev->usbnet->net->stats);
-#endif
+ struct net_device_stats *stats = &(dev->usbnet->net->stats);
struct qmiwds_stats dstats = {
.txok = (u32)-1,
@@ -1448,7 +1435,7 @@ static void wds_callback(struct qcusbnet *dev, u16 cid, void *data)
.rxbytesok = (u64)-1,
};
unsigned long flags;
-
+
if (!device_valid(dev)) {
DBG("Invalid device\n");
return;
@@ -1456,13 +1443,13 @@ static void wds_callback(struct qcusbnet *dev, u16 cid, void *data)
spin_lock_irqsave(&dev->qmi.clients_lock, flags);
ret = client_delread(dev, cid, 0, &rbuf, &rbufsize);
- spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
-
+ spin_unlock_irqrestore(&dev->qmi.clients_lock, flags);
+
if (!ret) {
DBG("WDS callback failed to get data\n");
return;
}
-
+
dstats.linkstate = !qc_isdown(dev, DOWN_NO_NDIS_CONNECTION);
dstats.reconfigure = false;
@@ -1472,25 +1459,25 @@ static void wds_callback(struct qcusbnet *dev, u16 cid, void *data)
} else {
if (dstats.txofl != (u32)-1)
stats->tx_fifo_errors = dstats.txofl;
-
+
if (dstats.rxofl != (u32)-1)
stats->rx_fifo_errors = dstats.rxofl;
if (dstats.txerr != (u32)-1)
stats->tx_errors = dstats.txerr;
-
+
if (dstats.rxerr != (u32)-1)
stats->rx_errors = dstats.rxerr;
if (dstats.txok != (u32)-1)
stats->tx_packets = dstats.txok + stats->tx_errors;
-
+
if (dstats.rxok != (u32)-1)
stats->rx_packets = dstats.rxok + stats->rx_errors;
if (dstats.txbytesok != (u64)-1)
stats->tx_bytes = dstats.txbytesok;
-
+
if (dstats.rxbytesok != (u64)-1)
stats->rx_bytes = dstats.rxbytesok;
@@ -1516,7 +1503,7 @@ static void wds_callback(struct qcusbnet *dev, u16 cid, void *data)
DBG("unable to setup next async read\n");
}
-static int setup_wds_callback(struct qcusbnet * dev)
+static int setup_wds_callback(struct qcusbnet *dev)
{
int result;
void *buf;
@@ -1527,7 +1514,7 @@ static int setup_wds_callback(struct qcusbnet * dev)
DBG("Invalid device\n");
return -EFAULT;
}
-
+
result = client_alloc(dev, QMIWDS);
if (result < 0)
return result;
@@ -1561,8 +1548,8 @@ static int setup_wds_callback(struct qcusbnet * dev)
}
result = usb_control_msg(dev->usbnet->udev,
- usb_sndctrlpipe(dev->usbnet->udev, 0),
- 0x22, 0x21, 1, 0, NULL, 0, 100);
+ usb_sndctrlpipe(dev->usbnet->udev, 0),
+ 0x22, 0x21, 1, 0, NULL, 0, 100);
if (result < 0) {
DBG("Bad SetControlLineState status %d\n", result);
return result;
@@ -1571,12 +1558,12 @@ static int setup_wds_callback(struct qcusbnet * dev)
return 0;
}
-static int qmidms_getmeid(struct qcusbnet * dev)
+static int qmidms_getmeid(struct qcusbnet *dev)
{
int result;
- void * wbuf;
+ void *wbuf;
size_t wbufsize;
- void * rbuf;
+ void *rbuf;
u16 rbufsize;
u16 cid;
diff --git a/drivers/net/usb/qcusbnet/structs.h b/drivers/net/usb/qcusbnet/structs.h
index 0f9f4eb..2999e62 100755
--- a/drivers/net/usb/qcusbnet/structs.h
+++ b/drivers/net/usb/qcusbnet/structs.h
@@ -27,22 +27,15 @@
#include <linux/cdev.h>
#include <linux/kthread.h>
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24)
- #include "usbnet.h"
-#else
- #include <linux/usb/usbnet.h>
-#endif
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
- #include <linux/fdtable.h>
-#else
- #include <linux/file.h>
-#endif
-
-#define DBG(format, arg...) \
- if (debug == 1) { \
- printk(KERN_INFO "QCUSBNet2k::%s " format, __FUNCTION__, ## arg); \
- }
+#include <linux/usb/usbnet.h>
+
+#include <linux/fdtable.h>
+
+#define DBG(fmt, arg...) \
+do { \
+ if (debug == 1) \
+ printk(KERN_INFO "QCUSBNet2k::%s " fmt, __func__, ##arg); \
+} while (0)
struct qcusbnet;
--
1.7.3.1.g432b3.dirty
^ permalink raw reply related
* [PATCH 0/2] qcusbnet: Cleanups
From: Joe Perches @ 2010-09-29 2:39 UTC (permalink / raw)
To: Elly Jones; +Cc: netdev, dbrownell, mjg59, jglasgow, msb, olofj
In-Reply-To: <20100928171026.GB6083@google.com>
Perhaps some of these cleanups are in order?
Joe Perches (2):
drivers/net/usb/qcusbnet: Checkpatch cleanups
drivers/net/usb/qcusbnet/qmidevice: Remove printhex, use print_hex_dump
drivers/net/usb/qcusbnet/qcusbnet.c | 201 ++++++----------
drivers/net/usb/qcusbnet/qmi.c | 32 ++--
drivers/net/usb/qcusbnet/qmidevice.c | 451 ++++++++++++++++------------------
drivers/net/usb/qcusbnet/qmidevice.h | 1 -
drivers/net/usb/qcusbnet/structs.h | 25 +--
5 files changed, 307 insertions(+), 403 deletions(-)
--
1.7.3.1.g432b3.dirty
^ permalink raw reply
* [PATCH] sctp: implement SIOCINQ ioctl() (take 3)
From: Diego Elio Pettenò @ 2010-09-29 1:51 UTC (permalink / raw)
To: netdev, linux-sctp; +Cc: Diego Elio 'Flameeyes' Pettenò
From: Diego Elio 'Flameeyes' Pettenò <flameeyes@gmail.com>
This simple patch copies the current approach for SIOCINQ ioctl() from DCCP
into SCTP so that the userland code working with SCTP can use a similar
interface across different protocols to know how much space to allocate for
a buffer.
Signed-off-by: Diego Elio Pettenò <flameeyes@gmail.com>
---
net/sctp/socket.c | 35 ++++++++++++++++++++++++++++++++++-
1 files changed, 34 insertions(+), 1 deletions(-)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ca44917..199ec05 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3595,7 +3595,40 @@ out:
/* The SCTP ioctl handler. */
SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
- return -ENOIOCTLCMD;
+ int rc = -ENOTCONN;
+
+ sctp_lock_sock(sk);
+
+ /*
+ * SEQPACKET-style sockets in LISTENING state are valid, for
+ * SCTP, so only discard TCP-style sockets in LISTENING state.
+ */
+ if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
+ goto out;
+
+ switch (cmd) {
+ case SIOCINQ: {
+ struct sk_buff *skb;
+ unsigned int amount = 0;
+
+ skb = skb_peek(&sk->sk_receive_queue);
+ if (skb != NULL) {
+ /*
+ * We will only return the amount of this packet since
+ * that is all that will be read.
+ */
+ amount = skb->len;
+ }
+ rc = put_user(amount, (int __user *)arg);
+ }
+ break;
+ default:
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+out:
+ sctp_release_sock(sk);
+ return rc;
}
/* This is the function which gets called during socket creation to
--
1.7.3
^ permalink raw reply related
* VLAN GARP triggers a lot of timers if linux compiled with VLAN_8021Q_GVRP
From: didier @ 2010-09-29 0:35 UTC (permalink / raw)
To: netdev; +Cc: kaber
Hi,
In my understanding GARP is using a periodic timer but in net/802/garp.c:
garp_join_timer_arm()
delay = (u64)msecs_to_jiffies(garp_join_time)* net_random() >> 32;
mod_timer(&app->join_timer, jiffies +delay)
Isn't this stuff triggering a *lot* of events?
Didier
^ permalink raw reply
* Re: pull-request: bluetooth-2.6 2010-09-27
From: Gustavo F. Padovan @ 2010-09-28 22:49 UTC (permalink / raw)
To: David Miller
Cc: linville-2XuSBdqkA4R54TAoqtyWWQ, marcel-kz+m5ild9QBg9hUCZPvPmw,
linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20100927.200016.226762808.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
* David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> [2010-09-27 20:00:16 -0700]:
> From: "Gustavo F. Padovan" <padovan-Y3ZbgMPKUGA34EUeqzHoZw@public.gmane.org>
> Date: Mon, 27 Sep 2010 23:30:35 -0300
>
> > And a fix for a deadlock issue between the sk_sndbuf and the backlog
> > queue in ERTM. The rest are also needed bug fixes.
>
> This fix is still under discussion.
>
> That change effects quite a few code paths. And when I looked
> at them, I was not at all convinced that dropping the socket
> lock like that is safe.
>
> Are you sure there are no pieces of socket or socket related state
> that might change under us while we drop that lock, which would thus
> make the operation suddenly invalid or cause a state corruption or
> crash?
We can group all the code paths in only two different code paths. One
wirh SCO, L2CAP Basic Mode and L2CAP Streaming Mode once they are very
similar and other for ERTM, a more complicated protocol.
For the first group the only bottom half action we have are incoming data,
which doesn't affect the sk states, and disconnection request, that can
change the sk states. We guarantee that this won't affect by checking the
sk_err after get the lock again. Looking to the code again we might
also want to check the sk->sk_shutdown value like TCP does inside
sk_stream_wait_memory().
Actually sk_stream_wait_memory is another point why it's safe to release
the lock and block waiting for memory. We've been doing that safely in
protocols like TCP, SCTP and DCCP for a long time.
Back to patch, the other code path it affects is the ERTM one, besides
the incoming data we have other bottom halves actions, but in the end the
only action that can affect ERTM flow is closing the channeli, but we are
prepared for that by checking the sk->sk_err and sk->sk_shutdown when we
get the lock back.
---
Bluetooth: Fix deadlock in the ERTM logic
The Enhanced Retransmission Mode(ERTM) is a realiable mode of operation
of the Bluetooth L2CAP layer. Think on it like a simplified version of
TCP.
The problem we were facing here was a deadlock. ERTM uses a backlog
queue to queue incomimg packets while the user is helding the lock. At
some moment the sk_sndbuf can be exceeded and we can't alloc new skbs
then the code sleep with the lock to wait for memory, that stalls the
ERTM connection once we can't read the acknowledgements packets in the
backlog queue to free memory and make the allocation of outcoming skb
successful.
This patch actually affect all users of bt_skb_send_alloc(), i.e., all
L2CAP modes and SCO.
We are safe against socket states changes or channels deletion while the
we are sleeping wait memory. Checking for the sk->sk_err and
sk->sk_shutdown make the code safe, since any action that can leave the
socket or the channel in a not usable state set one of the struct
members at least. Then we can check both of them when getting the lock
again and return with the proper error if something unexpected happens.
Signed-off-by: Gustavo F. Padovan <padovan-Y3ZbgMPKUGA34EUeqzHoZw@public.gmane.org>
Signed-off-by: Ulisses Furquim <ulisses-Y3ZbgMPKUGA34EUeqzHoZw@public.gmane.org>
---
include/net/bluetooth/bluetooth.h | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 27a902d..e8d64ba 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -161,12 +161,30 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l
{
struct sk_buff *skb;
+ release_sock(sk);
if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
skb_reserve(skb, BT_SKB_RESERVE);
bt_cb(skb)->incoming = 0;
}
+ lock_sock(sk);
+
+ if (!skb && *err)
+ return NULL;
+
+ *err = sock_error(sk);
+ if (*err)
+ goto out;
+
+ if (sk->sk_shutdown) {
+ *err = ECONNRESET;
+ goto out;
+ }
return skb;
+
+out:
+ kfree_skb(skb);
+ return NULL;
}
int bt_err(__u16 code);
--
1.7.3
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply related
* Re: [RFC] Online firmware upgrade in non-embedded systems
From: Carl-Daniel Hailfinger @ 2010-09-28 22:41 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev, linux-kernel, linux-mtd, sf-linux-drivers, flashrom
In-Reply-To: <1285696787.2282.45.camel@achroite.uk.solarflarecom.com>
[adding flashrom@flashrom.org to CC, senders will be whitelisted after a
short delay]
On 28.09.2010 19:59, Ben Hutchings wrote:
> Network and disk controllers normally have at least some firmware in
> flash to support their use as boot devices. [...]
>
> Currently the sfc network driver is optionally combined with an MTD
> driver (CONFIG_SFC_MTD) which exposes all upgradable firmware and
> configuration partitions in flash. This works nicely in kernels with
> MTD enabled, but since MTD is mainly used in embedded systems with
> on-board flash it is often disabled in distribution kernels and custom
> kernels alike. This leaves users of sfc unable to upgrade firmware
> without rebuilding the kernel or booting some other distribution. The
> lack of widespread MTD support is a regular cause of support requests.
>
> There are two main alternatives I'm aware of:
>
> - Use the ethtool ETHTOOL_SEEPROM [...]
>
> - Use the ethtool ETHTOOL_FLASHDEV command [..]
>
> Of course these are both specific to network devices; it seems deisrable
> to have a more general convention for online firmware upgrades. MTDs
> clearly are more generally applicable, and pretty much every computer
> does have flash storage for firmware and boot configuration, so perhaps
> it should be treated as more of a standard feature?
>
Given that the flashrom utility <http://www.flashrom.org/> (GPLv2)
supports flashing many network cards, SATA/PATA controllers, graphics
cards, and of course the main system firmware/BIOS/EFI, and it does that
from userspace without any kernel support, using flashrom for those
purposes makes sense IMHO.
flashrom works fine under Linux 2.4, 2.6 and pretty much every other OS
out there. There is a focus on x86, but MIPS, PowerPC and other
architectures are supported as well. flashrom is independent of the MTD
framework, so you don't need to boot a special kernel for a firmware
upgrade.
That said, writing a flashrom driver for your hardware is pretty easy.
You could even use existing kernel code for your device as a template
for the flashrom driver since the license is compatible.
If you have any questions, please ask.
Regards,
Carl-Daniel
^ permalink raw reply
* Re: [PATCH] net: Fix IPv6 PMTU disc. w/ asymmetric routes
From: Maciej Żenczykowski @ 2010-09-28 22:37 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Hideaki Yoshifuji
In-Reply-To: <20100928.135800.39205209.davem@davemloft.net>
> Please handle all 4 cases just like the ipv4 routing code does:
>
> { saddr = SADDR, ifindex = dev->ifindex }
> { saddr = SADDR, ifindex = 0 }
> { saddr = INADDR_ANY, ifindex = dev->ifindex }
> { saddr = INADDR_ANY, ifindex = 0 }
>
> I believe I've specifically asked for this every time someone mentioned that they wanted to fix this issue.
I believe that is exactly what the following code fragment from the
above patch does:
+ rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0);
+ rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex);
+ rt6_do_pmtu_disc(daddr, NULL, net, pmtu, 0);
+ rt6_do_pmtu_disc(daddr, NULL, net, pmtu, dev->ifindex);
The last two of these lines were added to the patch last time around
per your feedback - precisely to address this issue.
I reposted with those changes and you appeared to be ok with the
patch, and your only comment was to add a 'Signed-off-by' line.
Side note:
* I still think that handling the saddr == NULL ie. INADDR_ANY case is
entirely superfluous, since it doesn't actually iterate through all
possible source addresses. With IPv6 there can be many, many possible
source addresses (just think of link local vs global public vs privacy
addresses and then tack on 6to4 and mobility, etc... for example I see
13 ipv6 addresses on eth0 on my desktop at home, 12 of them globally
reachable).
* Currently PMTU discovery is broken. With this patch with all 4
lines we end up doing PMTU discovery per source address that isn't the
default source address. Without those last two lines we'd just do
PMTU discovery per source address. Not much of a difference, both
allow PMTU discovery to actually happen.
Except:
Imagine a machine with a 1500 MTU network card and 2 source addresses:
- one default v6 native 'A'
- one additional 6to4 address 'B'
The native address can reach the internet with a max MTU of 1500.
While due to source address based routing the 6to4 address goes
through a sit ipv4 based tunnel and thus has a max MTU of 1480 (1500 -
20 bytes IPv4 header).
Imagine a remote machine with v6 address 'Z' (our default address to
reach 'Z' is 'A').
Clearly the PMTU of A->Z is 1500, while the PMTU of B->Z is 1480.
[Assume there's nothing which would cause them to be lower.]
If you do PMTU discovery of A->Z, you will indeed get 1500, and mark
that as the PMTU of A->Z.
However if you do PMTU discovery of B->Z, you will indeed get 1480,
but you will mark that as the PMTU of both B->Z and A->Z (since A is
the default to reach Z).
Suddenly the PMTU of A->Z _needlessly and incorrectly_ dropped from
1500 to 1480 merely because of PMTU discovery being performed on B->Z.
And this is precisely why I think that adding those last two lines
that handle INADDR_ANY is actually more of a problem then solution
(indeed as far as I can tell, adding them doesn't actually fix any
problem - the code works just fine and performs PMTU discovery
correctly with just the first two lines).
Thankfully ending up with a lower MTU than actually possible is only a
slight performance problem, while not doing PMTU discovery correctly
at all (current state with asymmetric routing) is a big issue.
Hence regardless of whether this patch includes INADDR_ANY or not the
end result will still be an improvement.
> And the ipv4 side is a good guide in other ways, it uses a set of two arrays so you can just loop over them, making your rt6_do_pmtu_disc() calls along the way.
Sure, I can change it to use arrays, although I don't see any
particular improvement in performance (even if rt6_do_pmtu_disc was
inlined) or readability or anything.
^ 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