[PATCH 4/4] staging: wlan-ng: prism2sta: Use 'in situ' endian conversions in 'prism2sta_inf_chinforesults()'

Ricardo Silva rjpdasilva at gmail.com
Tue Jul 18 13:09:18 UTC 2017


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 at gmail.com>
---
 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



More information about the devel mailing list