Function 'prism2sta_inf_chinforesults()' decodes some little-endian 16-bit values from a received Channel Info Results info frame and stores them on the 'struct hfa384x' associated instance. To note that the structs and fields for storing both the little-endian (in info frame struct) and CPU byte order (in instance struct) values are the same ('struct hfa384x_ch_info_result'). Some sparse warnings are being triggered when accessing the little-endian values using 'le16_to_cpu()' from within 'prism2sta_inf_chinforesults()': prism2sta.c:1139:13: warning: cast to restricted __le16 prism2sta.c:1150:24: warning: cast to restricted __le16 prism2sta.c:1157:37: warning: cast to restricted __le16 prism2sta.c:1158:37: warning: cast to restricted __le16 prism2sta.c:1159:40: warning: cast to restricted __le16 Changing the relevant fields declarations to '__le16' won't fix the issue, because the same struct and fields are also used for storing the values in CPU byte order (which must be 'u16'). This way, use 'in situ' conversion on the info frame fields and then assign the converted values to the associated fields on the instance data side. Add a local 'le16_to_cpus_ret()' function as a helper for this process, doing the 'in situ' conversion and returning the converted value. The 'in situ' conversions on the info frame side fields is safe, in the sense that there are no posterior accesses to the (now already converted) values, otherwise any posterior accesses must consider that the conversion was already done. Signed-off-by: Ricardo Silva <rjpdasilva@xxxxxxxxx> --- drivers/staging/wlan-ng/prism2sta.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 8c347128e810..a549ef0e2ff4 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -132,6 +132,13 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, static void prism2sta_inf_psusercnt(struct wlandevice *wlandev, struct hfa384x_inf_frame *inf); +/* Convert from __le16 to u16 in situ and return converted value. */ +static inline u16 le16_to_cpus_ret(u16 *var) +{ + le16_to_cpus(var); + return *var; +} + /* * prism2sta_open * @@ -1136,7 +1143,7 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, unsigned int i, n; hw->channel_info.results.scanchannels = - le16_to_cpu(inf->info.chinforesult.scanchannels); + le16_to_cpus_ret(&inf->info.chinforesult.scanchannels); for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) { struct hfa384x_ch_info_result_sub *result; @@ -1147,16 +1154,16 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, continue; result = &inf->info.chinforesult.result[n]; - chan = le16_to_cpu(result->chid) - 1; + chan = le16_to_cpus_ret(&result->chid) - 1; if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX) continue; chinforesult = &hw->channel_info.results.result[chan]; chinforesult->chid = chan; - chinforesult->anl = le16_to_cpu(result->anl); - chinforesult->pnl = le16_to_cpu(result->pnl); - chinforesult->active = le16_to_cpu(result->active); + chinforesult->anl = le16_to_cpus_ret(&result->anl); + chinforesult->pnl = le16_to_cpus_ret(&result->pnl); + chinforesult->active = le16_to_cpus_ret(&result->active); pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", chan + 1, -- 2.13.2 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel