* I need help with a sparse warning
@ 2008-09-12 2:13 Larry Finger
2008-09-12 2:32 ` Steven Noonan
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Larry Finger @ 2008-09-12 2:13 UTC (permalink / raw)
To: LKML; +Cc: wireless
In file drivers/net/wireless/p54/p54common.c, the statement
priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]);
generates the sparse warning
.../p54common.c:185:29: warning: cast to restricted __le16
where bootrec->data is u32, and priv->rx_mtu is u16.
What should be done to eliminate this warning?
Thanks,
Larry
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 2:13 I need help with a sparse warning Larry Finger
@ 2008-09-12 2:32 ` Steven Noonan
2008-09-12 2:58 ` Larry Finger
2008-09-12 2:39 ` Roland Dreier
2008-09-12 2:44 ` Alexey Dobriyan
2 siblings, 1 reply; 10+ messages in thread
From: Steven Noonan @ 2008-09-12 2:32 UTC (permalink / raw)
To: Larry Finger; +Cc: LKML, wireless
On Thu, Sep 11, 2008 at 7:13 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote:
> In file drivers/net/wireless/p54/p54common.c, the statement
>
> priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]);
>
> generates the sparse warning
>
> .../p54common.c:185:29: warning: cast to restricted __le16
>
> where bootrec->data is u32, and priv->rx_mtu is u16.
>
(Whoops, didn't CC the mailing lists. Sorry about the double-message, Larry.)
If priv->rx_mtu is u16, I'm surprised it doesn't get noisy about the
size_t cast. Unless the machine it's being compiled on is 16-bit, that
should throw a truncation warning, because size_t should be a 32-bit
integer on 32-bit machines (typically).
I think if you change the (__le16) cast to (__le16 __force) it will
stop warning you about that particular issue.
- Steven
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 2:13 I need help with a sparse warning Larry Finger
2008-09-12 2:32 ` Steven Noonan
@ 2008-09-12 2:39 ` Roland Dreier
2008-09-12 3:05 ` Larry Finger
2008-09-12 2:44 ` Alexey Dobriyan
2 siblings, 1 reply; 10+ messages in thread
From: Roland Dreier @ 2008-09-12 2:39 UTC (permalink / raw)
To: Larry Finger; +Cc: LKML, wireless
> In file drivers/net/wireless/p54/p54common.c, the statement
>
> priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]);
[I don't see this code in Linus's tree]
>
> generates the sparse warning
>
> .../p54common.c:185:29: warning: cast to restricted __le16
>
> where bootrec->data is u32, and priv->rx_mtu is u16.
>
> What should be done to eliminate this warning?
the code in question looks buggy to me. Since bootrec->data[10] is u32,
casting it to a 16-bit type is going to take a different 2 bytes out of
the 4 bytes depending on the endianness of the system the driver is
built for. And I assume you are parsing some fixed-layout thing that
the firmware is giving you or something like that.
I would guess you want something like:
priv->rx_mtu = le16_to_cpu(((__force __le16 *) bootrec->data)[20]);
(__force is what shuts up sparse, and as far as I can see, the size_t
cast is useless, since the result will be promoted anyway)
- R.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 2:13 I need help with a sparse warning Larry Finger
2008-09-12 2:32 ` Steven Noonan
2008-09-12 2:39 ` Roland Dreier
@ 2008-09-12 2:44 ` Alexey Dobriyan
2 siblings, 0 replies; 10+ messages in thread
From: Alexey Dobriyan @ 2008-09-12 2:44 UTC (permalink / raw)
To: Larry Finger; +Cc: LKML, wireless
On Thu, Sep 11, 2008 at 09:13:20PM -0500, Larry Finger wrote:
> In file drivers/net/wireless/p54/p54common.c, the statement
>
> priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]);
>
> generates the sparse warning
>
> .../p54common.c:185:29: warning: cast to restricted __le16
>
> where bootrec->data is u32, and priv->rx_mtu is u16.
>
> What should be done to eliminate this warning?
What is the intent?
MTU is 2-byte little-endian starting at 40-th byte?
Oh, and size_t cast is pointless.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 2:32 ` Steven Noonan
@ 2008-09-12 2:58 ` Larry Finger
2008-09-12 3:04 ` Roland Dreier
2008-09-12 15:25 ` Michael Buesch
0 siblings, 2 replies; 10+ messages in thread
From: Larry Finger @ 2008-09-12 2:58 UTC (permalink / raw)
To: Steven Noonan; +Cc: LKML, wireless
Steven Noonan wrote:
> On Thu, Sep 11, 2008 at 7:13 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote:
>> In file drivers/net/wireless/p54/p54common.c, the statement
>>
>> priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]);
>>
>> generates the sparse warning
>>
>> .../p54common.c:185:29: warning: cast to restricted __le16
>>
>> where bootrec->data is u32, and priv->rx_mtu is u16.
>>
>
> (Whoops, didn't CC the mailing lists. Sorry about the double-message, Larry.)
>
> If priv->rx_mtu is u16, I'm surprised it doesn't get noisy about the
> size_t cast. Unless the machine it's being compiled on is 16-bit, that
> should throw a truncation warning, because size_t should be a 32-bit
> integer on 32-bit machines (typically).
>
> I think if you change the (__le16) cast to (__le16 __force) it will
> stop warning you about that particular issue.
This one gets rid of the sparse warning.
priv->rx_mtu = le16_to_cpu((__le16 __force)
bootrec->data[10]);
Thanks,
Larry
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 2:58 ` Larry Finger
@ 2008-09-12 3:04 ` Roland Dreier
2008-09-12 3:07 ` Larry Finger
2008-09-12 15:25 ` Michael Buesch
1 sibling, 1 reply; 10+ messages in thread
From: Roland Dreier @ 2008-09-12 3:04 UTC (permalink / raw)
To: Larry Finger; +Cc: Steven Noonan, LKML, wireless
> This one gets rid of the sparse warning.
>
> priv->rx_mtu = le16_to_cpu((__le16 __force)
> bootrec->data[10]);
Yes but does it actually work on both big and little endian systems?
(See my previous email)
- R.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 2:39 ` Roland Dreier
@ 2008-09-12 3:05 ` Larry Finger
2008-09-12 17:12 ` Pavel Roskin
0 siblings, 1 reply; 10+ messages in thread
From: Larry Finger @ 2008-09-12 3:05 UTC (permalink / raw)
To: Roland Dreier; +Cc: LKML, wireless
Roland Dreier wrote:
> > In file drivers/net/wireless/p54/p54common.c, the statement
> >
> > priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]);
>
> [I don't see this code in Linus's tree]
It is in wireless-testing.
>
> the code in question looks buggy to me. Since bootrec->data[10] is u32,
> casting it to a 16-bit type is going to take a different 2 bytes out of
> the 4 bytes depending on the endianness of the system the driver is
> built for. And I assume you are parsing some fixed-layout thing that
> the firmware is giving you or something like that.
>
> I would guess you want something like:
>
> priv->rx_mtu = le16_to_cpu(((__force __le16 *) bootrec->data)[20]);
>
> (__force is what shuts up sparse, and as far as I can see, the size_t
> cast is useless, since the result will be promoted anyway)
Yes, that one works. As you suspected, this section is parsing data
from the firmware.
When I started, there were 18 sparse warnings, and a number of them
were accesses of little-endian variables without an appropriate
leXX_to_cpu() conversion. Obviously, this code has never been tested
on a big-endian machine.
Thanks,
Larry
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 3:04 ` Roland Dreier
@ 2008-09-12 3:07 ` Larry Finger
0 siblings, 0 replies; 10+ messages in thread
From: Larry Finger @ 2008-09-12 3:07 UTC (permalink / raw)
To: Roland Dreier; +Cc: Steven Noonan, LKML, wireless
Roland Dreier wrote:
> > This one gets rid of the sparse warning.
> >
> > priv->rx_mtu = le16_to_cpu((__le16 __force)
> > bootrec->data[10]);
>
> Yes but does it actually work on both big and little endian systems?
> (See my previous email)
I don't know, but as my previous email stated, the code could not
possibly have worked on a big-endian system before I started the
sparse cleanup. I don't have access to anything but little-endian
hardware.
Larry
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 2:58 ` Larry Finger
2008-09-12 3:04 ` Roland Dreier
@ 2008-09-12 15:25 ` Michael Buesch
1 sibling, 0 replies; 10+ messages in thread
From: Michael Buesch @ 2008-09-12 15:25 UTC (permalink / raw)
To: Larry Finger; +Cc: Steven Noonan, LKML, wireless
On Friday 12 September 2008, Larry Finger wrote:
> Steven Noonan wrote:
> > On Thu, Sep 11, 2008 at 7:13 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote:
> >> In file drivers/net/wireless/p54/p54common.c, the statement
> >>
> >> priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]);
> >>
> >> generates the sparse warning
> >>
> >> .../p54common.c:185:29: warning: cast to restricted __le16
> >>
> >> where bootrec->data is u32, and priv->rx_mtu is u16.
> >>
> >
> > (Whoops, didn't CC the mailing lists. Sorry about the double-message, Larry.)
> >
> > If priv->rx_mtu is u16, I'm surprised it doesn't get noisy about the
> > size_t cast. Unless the machine it's being compiled on is 16-bit, that
> > should throw a truncation warning, because size_t should be a 32-bit
> > integer on 32-bit machines (typically).
> >
> > I think if you change the (__le16) cast to (__le16 __force) it will
> > stop warning you about that particular issue.
>
> This one gets rid of the sparse warning.
>
> priv->rx_mtu = le16_to_cpu((__le16 __force)
> bootrec->data[10]);
I think you should rather fix the type of bootrec->data.
If it is u32, but the data in fact is __le16, please fix the struct instead
of adding dangerous casts.
Note that this is especially dangerous, because you cast between different
typesizes and endianesses at the same time.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning
2008-09-12 3:05 ` Larry Finger
@ 2008-09-12 17:12 ` Pavel Roskin
0 siblings, 0 replies; 10+ messages in thread
From: Pavel Roskin @ 2008-09-12 17:12 UTC (permalink / raw)
To: Larry Finger; +Cc: Roland Dreier, LKML, wireless
On Thu, 2008-09-11 at 22:05 -0500, Larry Finger wrote:
> > I would guess you want something like:
> >
> > priv->rx_mtu = le16_to_cpu(((__force __le16 *) bootrec->data)[20]);
> >
> > (__force is what shuts up sparse, and as far as I can see, the size_t
> > cast is useless, since the result will be promoted anyway)
>
> Yes, that one works. As you suspected, this section is parsing data
> from the firmware.
I believe __force should be the last resort. If you want to read a
16-bit little endian value at the given offset, I suggest that you use
le16_to_cpup(), which operates on pointers and does the cast for you.
A better but more elaborate solution would be to define a structure that
would have __le16 rx_mtu at the offset 40. Then you can cast bootrec to
that structure and apply le16_to_cpu() to that field.
--
Regards,
Pavel Roskin
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-09-12 17:12 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-12 2:13 I need help with a sparse warning Larry Finger
2008-09-12 2:32 ` Steven Noonan
2008-09-12 2:58 ` Larry Finger
2008-09-12 3:04 ` Roland Dreier
2008-09-12 3:07 ` Larry Finger
2008-09-12 15:25 ` Michael Buesch
2008-09-12 2:39 ` Roland Dreier
2008-09-12 3:05 ` Larry Finger
2008-09-12 17:12 ` Pavel Roskin
2008-09-12 2:44 ` Alexey Dobriyan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).