linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* 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).