LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
@ 2021-08-20 17:07 Pavel Skripkin
  2021-08-20 17:07 ` [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling Pavel Skripkin
                   ` (4 more replies)
  0 siblings, 5 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-20 17:07 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

Hi, Greg, Larry and Phillip!

I noticed, that new staging driver was added like 3 weeks ago and I decided
to look at the code, because drivers in staging directory are always buggy.

The first thing I noticed is *no one* was checking read operations result, but
it can fail and driver may start writing random stack values into registers. It
can cause driver misbehavior or device misbehavior.

To avoid this type of bugs, i've expanded read() API with error parametr,
which will be initialized to error if read fails. It helps callers to
break/return earlier and don't write random values to registers or to rely
on random values.

Why is this pacth series RFC?
  1. I don't have this device and I cannot test these changes.
  2. I don't know how to handle errors in each particular case. For now, function
     just returns or returns an error. That's all. I hope, driver maintainers will
     help with these bits.
  3. I guess, I handled not all uninit value bugs here. I hope, I fixed
     at least half of them

This series was build-tested and made on top of staging-testing branch


With regards,
Pavel Skripkin

Pavel Skripkin (3):
  staging: r8188eu: add proper rtw_read* error handling
  staging: r8188eu: add error handling to ReadFuse
  staging: r8188eu: add error argument to read_macreg

 drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
 drivers/staging/r8188eu/core/rtw_efuse.c      | 119 +++--
 drivers/staging/r8188eu/core/rtw_io.c         |  18 +-
 drivers/staging/r8188eu/core/rtw_mp.c         |  38 +-
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  20 +-
 drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   6 +-
 drivers/staging/r8188eu/core/rtw_sreset.c     |   7 +-
 drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
 drivers/staging/r8188eu/hal/hal_com.c         |  22 +-
 drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
 drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  37 +-
 drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 260 ++++++++---
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  26 +-
 drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  20 +-
 drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  17 +-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 412 ++++++++++++++----
 drivers/staging/r8188eu/hal/usb_ops_linux.c   |  55 ++-
 drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
 .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
 drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
 drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
 drivers/staging/r8188eu/include/rtw_mp.h      |   2 +-
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 168 +++++--
 drivers/staging/r8188eu/os_dep/usb_intf.c     |   4 +-
 26 files changed, 1072 insertions(+), 301 deletions(-)

-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling
  2021-08-20 17:07 [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
@ 2021-08-20 17:07 ` Pavel Skripkin
  2021-08-20 21:50   ` Pavel Skripkin
                     ` (2 more replies)
  2021-08-20 17:07 ` [PATCH RFC 2/3] staging: r8188eu: add error handling to ReadFuse Pavel Skripkin
                   ` (3 subsequent siblings)
  4 siblings, 3 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-20 17:07 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

rtw_read*() functions call usb_read* inside. These functions could fail
in some cases; for example: failed to receive control message. These
cases should be handled to prevent uninit value bugs, since usb_read*
functions blindly return stack variable without checking if this value
_actualy_ initialized.

To achive it, all usb_read* and rtw_read*() argument list is expanded
with pointer to error and added error usbctrl_vendorreq() error checking.
If transfer is successful error will be initialized to 0 otherwise to
error returned from usb_control_msg().

To not break the build, added error checking for rtw_read*() call all
across the driver.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
 drivers/staging/r8188eu/core/rtw_efuse.c      |  83 +++-
 drivers/staging/r8188eu/core/rtw_io.c         |  18 +-
 drivers/staging/r8188eu/core/rtw_mp.c         |  37 +-
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  20 +-
 drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   6 +-
 drivers/staging/r8188eu/core/rtw_sreset.c     |   7 +-
 drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
 drivers/staging/r8188eu/hal/hal_com.c         |  22 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
 drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  37 +-
 drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 198 +++++++--
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  26 +-
 drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  20 +-
 drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  17 +-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 394 ++++++++++++++----
 drivers/staging/r8188eu/hal/usb_ops_linux.c   |  16 +-
 drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 168 +++++---
 20 files changed, 941 insertions(+), 252 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 2ee64cef73f7..9f8df3cf3070 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -73,8 +73,9 @@ int proc_get_read_reg(char *page, char **start,
 {
 	struct net_device *dev = data;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
+	int error;
 	int len = 0;
+	u32 tmp;
 
 	if (proc_get_read_addr == 0xeeeeeeee) {
 		*eof = 1;
@@ -83,19 +84,35 @@ int proc_get_read_reg(char *page, char **start,
 
 	switch (proc_get_read_len) {
 	case 1:
-		len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr));
+		tmp = rtw_read8(padapter, proc_get_read_addr, &error);
+
+		if (error)
+			goto end;
+
+		len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, (u8) tmp);
 		break;
 	case 2:
-		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
+		tmp = rtw_read16(padapter, proc_get_read_addr, &error);
+
+		if (error)
+			goto end;
+
+		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, (u16) tmp);
 		break;
 	case 4:
-		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
+		tmp = rtw_read32(padapter, proc_get_read_addr, &error);
+
+		if (error)
+			goto end;
+
+		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, tmp);
 		break;
 	default:
 		len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
 		break;
 	}
 
+end:
 	*eof = 1;
 	return len;
 }
@@ -305,13 +322,20 @@ int proc_get_mac_reg_dump1(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 
 	for (i = 0x0; i < 0x300; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		tmp = rtw_read32(padapter, i, &error);
+		if (error)
+			return len;
+	
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -328,13 +352,20 @@ int proc_get_mac_reg_dump2(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 	memset(page, 0, count);
 	for (i = 0x300; i < 0x600; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+	
+		tmp = rtw_read32(padapter, i, &error);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -351,13 +382,20 @@ int proc_get_mac_reg_dump3(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 
 	for (i = 0x600; i < 0x800; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+		
+		tmp = rtw_read32(padapter, i, &error);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -374,12 +412,19 @@ int proc_get_bb_reg_dump1(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0x800; i < 0xB00; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		tmp = rtw_read32(padapter, i, &error);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -395,12 +440,19 @@ int proc_get_bb_reg_dump2(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0xB00; i < 0xE00; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		tmp = rtw_read32(padapter, i, &error);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -416,12 +468,19 @@ int proc_get_bb_reg_dump3(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0xE00; i < 0x1000; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+		
+		tmp = rtw_read32(padapter, i, &error);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index decccf7622f0..47ff73b28380 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -159,6 +159,7 @@ ReadEFuseByte(
 	u32 value32;
 	u8 readbyte;
 	u16 retry;
+	int error;
 
 	if (pseudo) {
 		Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
@@ -167,18 +168,27 @@ ReadEFuseByte(
 
 	/* Write Address */
 	rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
-	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);
+	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2, &error);
+	if (error)
+		return;
 	rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
 
 	/* Write bit 32 0 */
-	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3);
+	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
+	if (error)
+		return;
 	rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
 
 	/* Check bit 32 read-ready */
 	retry = 0;
-	value32 = rtw_read32(Adapter, EFUSE_CTRL);
+	value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
+	if (error)
+		return;
+
 	while (!(((value32 >> 24) & 0xff) & 0x80)  && (retry < 10000)) {
-		value32 = rtw_read32(Adapter, EFUSE_CTRL);
+		value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
+		if (error)
+			return;
 		retry++;
 	}
 
@@ -187,7 +197,9 @@ ReadEFuseByte(
 	/*  Designer says that there shall be some delay after ready bit is set, or the */
 	/*  result will always stay on last data we read. */
 	udelay(50);
-	value32 = rtw_read32(Adapter, EFUSE_CTRL);
+	value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
+	if (error)
+		return;
 
 	*pbuf = (u8)(value32 & 0xff);
 }
@@ -244,6 +256,7 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
 	u8 temp = {0x00};
 	u32 k = 0;
 	u16 contentLen = 0;
+	int error;
 
 	EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
 
@@ -251,27 +264,41 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
 		/* Write E-fuse Register address bit0~7 */
 		temp = Address & 0xFF;
 		rtw_write8(Adapter, EFUSE_CTRL + 1, temp);
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2);
+		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2, &error);
+		if (error)
+			return 0xFF;
+
 		/* Write E-fuse Register address bit8~9 */
 		temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
 		rtw_write8(Adapter, EFUSE_CTRL + 2, temp);
 
 		/* Write 0x30[31]= 0 */
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
+		if (error)
+			return 0xFF;
+
 		temp = Bytetemp & 0x7F;
 		rtw_write8(Adapter, EFUSE_CTRL + 3, temp);
 
 		/* Wait Write-ready (0x30[31]= 1) */
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
+		if (error)
+			return 0xFF;
+
 		while (!(Bytetemp & 0x80)) {
-			Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+			Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
+			if (error)
+				return 0xFF;
+
 			k++;
 			if (k == 1000) {
 				k = 0;
 				break;
 			}
 		}
-		data = rtw_read8(Adapter, EFUSE_CTRL);
+		data = rtw_read8(Adapter, EFUSE_CTRL, &error);
+		if (error)
+			return 0xFF;
 		return data;
 	} else {
 		return 0xFF;
@@ -284,6 +311,8 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
 {
 	u8 tmpidx = 0;
 	u8 result;
+	u8 tmp;
+	int error;
 
 	if (pseudo) {
 		result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
@@ -292,15 +321,28 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
 	/*  -----------------e-fuse reg ctrl --------------------------------- */
 	/* address */
 	rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
+	
+	tmp = rtw_read8(pAdapter, EFUSE_CTRL + 2, &error);
+	if (error)
+		return false;
+
 	rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
-		   (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
+		   (tmp & 0xFC));
 
 	rtw_write8(pAdapter, EFUSE_CTRL + 3,  0x72);/* read cmd */
 
-	while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
+	tmp = rtw_read8(pAdapter, EFUSE_CTRL + 3, &error);
+	if (error)
+		return false;
+
+	while (!(0x80 & tmp) && (tmpidx < 100))
 		tmpidx++;
 	if (tmpidx < 100) {
-		*data = rtw_read8(pAdapter, EFUSE_CTRL);
+		tmp = rtw_read8(pAdapter, EFUSE_CTRL, &error);\
+		if (error)
+			return false;
+
+		*data = tmp;
 		result = true;
 	} else {
 		*data = 0xff;
@@ -314,6 +356,8 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
 {
 	u8 tmpidx = 0;
 	u8 result;
+	u8 tmp;
+	int error;
 
 	if (pseudo) {
 		result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
@@ -323,14 +367,23 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
 	/*  -----------------e-fuse reg ctrl --------------------------------- */
 	/* address */
 	rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
+	
+	tmp = rtw_read8(pAdapter, EFUSE_CTRL + 2, &error);
+	if (error)
+		return false;
+
 	rtw_write8(pAdapter, EFUSE_CTRL + 2,
-		   (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) |
+		   (tmp & 0xFC) |
 		   (u8)((addr >> 8) & 0x03));
 	rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */
 
 	rtw_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);/* write cmd */
 
-	while ((0x80 &  rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
+	tmp = rtw_read8(pAdapter, EFUSE_CTRL + 3, &error);
+	if (error)
+		return false;
+
+	while ((0x80 & tmp) && (tmpidx < 100))
 		tmpidx++;
 
 	if (tmpidx < 100)
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index cde0205816b1..d9684aa144c8 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -34,44 +34,44 @@ jackson@realtek.com.tw
 #define rtw_cpu_to_le16(val)		cpu_to_le16(val)
 #define rtw_cpu_to_le32(val)		cpu_to_le32(val)
 
-u8 _rtw_read8(struct adapter *adapter, u32 addr)
+u8 _rtw_read8(struct adapter *adapter, u32 addr, int *error)
 {
 	u8 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl *pintfhdl = &pio_priv->intf;
-	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
+	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr, int *error);
 
 
 	_read8 = pintfhdl->io_ops._read8;
-	r_val = _read8(pintfhdl, addr);
+	r_val = _read8(pintfhdl, addr, error);
 
 	return r_val;
 }
 
-u16 _rtw_read16(struct adapter *adapter, u32 addr)
+u16 _rtw_read16(struct adapter *adapter, u32 addr, int *error)
 {
 	u16 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
-	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr, int *error);
 
 	_read16 = pintfhdl->io_ops._read16;
 
-	r_val = _read16(pintfhdl, addr);
+	r_val = _read16(pintfhdl, addr, error);
 
 	return r_val;
 }
 
-u32 _rtw_read32(struct adapter *adapter, u32 addr)
+u32 _rtw_read32(struct adapter *adapter, u32 addr, int *error)
 {
 	u32 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
-	u32	(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+	u32	(*_read32)(struct intf_hdl *pintfhdl, u32 addr, int *error);
 
 	_read32 = pintfhdl->io_ops._read32;
 
-	r_val = _read32(pintfhdl, addr);
+	r_val = _read32(pintfhdl, addr, error);
 
 	return r_val;
 }
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 93bb683b628f..601a1fd5d4e7 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -10,16 +10,17 @@
 u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
 {
 	u32 val = 0;
+	int error;
 
 	switch (sz) {
 	case 1:
-		val = rtw_read8(padapter, addr);
+		val = rtw_read8(padapter, addr, &error);
 		break;
 	case 2:
-		val = rtw_read16(padapter, addr);
+		val = rtw_read16(padapter, addr, &error);
 		break;
 	case 4:
-		val = rtw_read32(padapter, addr);
+		val = rtw_read32(padapter, addr, &error);
 		break;
 	default:
 		val = 0xffffffff;
@@ -282,10 +283,14 @@ void GetPowerTracking(struct adapter *padapter, u8 *enable)
 static void disable_dm(struct adapter *padapter)
 {
 	u8 v8;
+	int error;
 
 	/* 3 1. disable firmware dynamic mechanism */
 	/*  disable Power Training, Rate Adaptive */
-	v8 = rtw_read8(padapter, REG_BCN_CTRL);
+	v8 = rtw_read8(padapter, REG_BCN_CTRL, &error);
+	if (error)
+		return;
+
 	v8 &= ~EN_BCN_FUNCTION;
 	rtw_write8(padapter, REG_BCN_CTRL, v8);
 
@@ -310,6 +315,7 @@ s32 mp_start_test(struct adapter *padapter)
 	struct mp_priv *pmppriv = &padapter->mppriv;
 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
+	int error;
 
 	padapter->registrypriv.mp_mode = 1;
 	pmppriv->bSetTxPower = 0;		/* for  manually set tx power */
@@ -403,7 +409,11 @@ s32 mp_start_test(struct adapter *padapter)
 
 	if (res == _SUCCESS) {
 		/*  set MSR to WIFI_FW_ADHOC_STATE */
-		val8 = rtw_read8(padapter, MSR) & 0xFC; /*  0x0102 */
+		val8 = rtw_read8(padapter, MSR, &error);
+		if (error)
+			return _FAIL;
+
+		val8 &= 0xFC; /*  0x0102 */
 		val8 |= WIFI_FW_ADHOC_STATE;
 		rtw_write8(padapter, MSR, val8); /*  Link in ad hoc network */
 	}
@@ -795,12 +805,17 @@ static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
 {
 	/* selection */
 	u32 phyrx_set = 0, count = 0;
+	int error;
 
 	phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
 	rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
 
 	/* Read packet count */
-	count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
+	count = rtw_read32(pAdapter, REG_RXERR_RPT, &error);
+	if (error)
+		return 0;
+
+	count &= RXERR_COUNTER_MASK;
 
 	return count;
 }
@@ -833,8 +848,12 @@ u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
 static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
 {
 	int psd_val;
+	int error;
+
+	psd_val = rtw_read32(pAdapter, 0x808, &error);
+	if (error)
+		return error;
 
-	psd_val = rtw_read32(pAdapter, 0x808);
 	psd_val &= 0xFFBFFC00;
 	psd_val |= point;
 
@@ -844,7 +863,9 @@ static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
 
 	rtw_write32(pAdapter, 0x808, psd_val);
 	mdelay(1);
-	psd_val = rtw_read32(pAdapter, 0x8B4);
+	psd_val = rtw_read32(pAdapter, 0x8B4, &error);
+	if (error)
+		return error;
 
 	psd_val &= 0x0000FFFF;
 
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c85f8e467337..ad004b176f94 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -629,9 +629,10 @@ int rtl8188eu_oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv)
 int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 {
 	struct mp_rw_reg *RegRWStruct;
-	u32		offset, width;
+	u32		offset, width, tmp;
 	int status = NDIS_STATUS_SUCCESS;
 	struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
+	int error;
 
 	if (poid_par_priv->type_of_oid != QUERY_OID)
 		return NDIS_STATUS_NOT_ACCEPTED;
@@ -647,17 +648,28 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 
 	switch (width) {
 	case 1:
-		RegRWStruct->value = rtw_read8(Adapter, offset);
+		tmp = rtw_read8(Adapter, offset, &error);
+		if (error)
+			return NDIS_STATUS_FAILURE;
+
 		break;
 	case 2:
-		RegRWStruct->value = rtw_read16(Adapter, offset);
+		tmp = rtw_read16(Adapter, offset, &error);
+		if (error)
+			return NDIS_STATUS_FAILURE;
+
 		break;
 	default:
 		width = 4;
-		RegRWStruct->value = rtw_read32(Adapter, offset);
+		tmp = rtw_read32(Adapter, offset, &error);
+		if (error)
+			return NDIS_STATUS_FAILURE;
+
 		break;
 	}
 
+	RegRWStruct->value = tmp;
+
 	_irqlevel_changed_(&oldirql, RAISE);
 
 	*poid_par_priv->bytes_rw = width;
diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
index c3897b29121c..f4accd0b01d8 100644
--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
@@ -55,6 +55,8 @@ int ips_leave(struct adapter *padapter)
 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	int result = _SUCCESS;
 	int keyid;
+	u32 tmp;
+	int error;
 
 	_enter_pwrlock(&pwrpriv->lock);
 
@@ -83,7 +85,9 @@ int ips_leave(struct adapter *padapter)
 			}
 		}
 
-		DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
+		tmp = rtw_read32(padapter, 0x4c, &error);
+		if (!error)
+			DBG_88E("==> ips_leave.....LED(0x%08x)...\n", tmp);
 		pwrpriv->bips_processing = false;
 
 		pwrpriv->bkeepfwalive = false;
diff --git a/drivers/staging/r8188eu/core/rtw_sreset.c b/drivers/staging/r8188eu/core/rtw_sreset.c
index 8e1bc62e74e5..1ac3f5c6bdec 100644
--- a/drivers/staging/r8188eu/core/rtw_sreset.c
+++ b/drivers/staging/r8188eu/core/rtw_sreset.c
@@ -29,13 +29,16 @@ u8 sreset_get_wifi_status(struct adapter *padapter)
 {
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+	int error;
 	u8 status = WIFI_STATUS_SUCCESS;
 	u32 val32 = 0;
 
 	if (psrtpriv->silent_reset_inprogress)
 		return status;
-	val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
+	val32 = rtw_read32(padapter, REG_TXDMA_STATUS, &error);
+	if (error)
+		return WIFI_MAC_TXDMA_ERROR;
+
 	if (val32 == 0xeaeaeaea) {
 		psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
 	} else if (val32 != 0) {
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
index 0fd11aca7ac7..ed24d904e3f6 100644
--- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
@@ -35,6 +35,7 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 	u32 offset = 0;
 	u32 poll_count = 0; /*  polling autoload done. */
 	u32 max_poll_count = 5000;
+	int error;
 
 	do {
 		pwrcfgcmd = pwrseqcmd[aryidx];
@@ -48,7 +49,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
 
 				/*  Read the value from system register */
-				value = rtw_read8(padapter, offset);
+				value = rtw_read8(padapter, offset, &error);
+				if (error)
+					return false;
 
 				value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
 				value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
@@ -60,7 +63,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 				poll_bit = false;
 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
 				do {
-					value = rtw_read8(padapter, offset);
+					value = rtw_read8(padapter, offset, &error);
+					if (error)
+						return false;
 
 					value &= GET_PWR_CFG_MASK(pwrcfgcmd);
 					if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c
index f09d4d49b159..b6cbbf2275c3 100644
--- a/drivers/staging/r8188eu/hal/hal_com.c
+++ b/drivers/staging/r8188eu/hal/hal_com.c
@@ -319,13 +319,15 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
 {
 	s32 ret = _FAIL;
 	struct c2h_evt_hdr *c2h_evt;
-	int i;
+	int i, error;
 	u8 trigger;
 
 	if (!buf)
 		goto exit;
 
-	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
+	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR, &error);
+	if (error)
+		goto exit;
 
 	if (trigger == C2H_EVT_HOST_CLOSE)
 		goto exit; /* Not ready */
@@ -336,13 +338,21 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
 
 	memset(c2h_evt, 0, 16);
 
-	*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
-	*(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
+	*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, &error);
+	if (error)
+		goto clear_evt;
+
+	*(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, &error);
+	if (error)
+		;
 
 	/* Read the content */
-	for (i = 0; i < c2h_evt->plen; i++)
+	for (i = 0; i < c2h_evt->plen; i++) {
 		c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
-						sizeof(*c2h_evt) + i);
+						sizeof(*c2h_evt) + i, &error);
+		if (error)
+			goto clear_evt;
+	}
 
 	ret = _SUCCESS;
 
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 5a01495d74bc..cedc68152401 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -7,19 +7,25 @@
 u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read8(Adapter, RegAddr);
+	int error;
+
+	return rtw_read8(Adapter, RegAddr, &error);
 }
 
 u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read16(Adapter, RegAddr);
+	int error;
+
+	return rtw_read16(Adapter, RegAddr, &error);
 }
 
 u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read32(Adapter, RegAddr);
+	int error;
+
+	return rtw_read32(Adapter, RegAddr, &error);
 }
 
 void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
index 3e1a45030bc8..4447fa8de275 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
@@ -21,11 +21,15 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
 {
 	u8 read_down = false;
 	int	retry_cnts = 100;
-
+	int error;
 	u8 valid;
 
 	do {
-		valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
+		valid = rtw_read8(adapt, REG_HMETFR, &error);
+		if (error)
+			continue;
+
+		valid &= BIT(msgbox_num);
 		if (0 == valid)
 			read_down = true;
 	} while ((!read_down) && (retry_cnts--));
@@ -580,6 +584,8 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 	bool	bcn_valid = false;
 	u8 DLBcnCount = 0;
 	u32 poll = 0;
+	u8 tmp;
+	int error;
 
 	DBG_88E("%s mstatus(%x)\n", __func__, mstatus);
 
@@ -596,8 +602,17 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 		/*  Disable Hw protection for a time which revserd for Hw sending beacon. */
 		/*  Fix download reserved page packet fail that access collision with the protection time. */
 		/*  2010.05.11. Added by tynli. */
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3)));
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4));
+		tmp = rtw_read8(adapt, REG_BCN_CTRL, &error);
+		if (error)
+			return;
+
+		rtw_write8(adapt, REG_BCN_CTRL, tmp & (~BIT(3)));
+
+		tmp = rtw_read8(adapt, REG_BCN_CTRL, &error);
+		if (error)
+			return;
+
+		rtw_write8(adapt, REG_BCN_CTRL, tmp | BIT(4));
 
 		if (haldata->RegFwHwTxQCtrl & BIT(6)) {
 			DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
@@ -639,8 +654,18 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 		/*  */
 
 		/*  Enable Bcn */
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3));
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4)));
+
+		tmp = rtw_read8(adapt, REG_BCN_CTRL, &error);
+		if (error)
+			return;
+
+		rtw_write8(adapt, REG_BCN_CTRL, tmp | BIT(3));
+
+		tmp = rtw_read8(adapt, REG_BCN_CTRL, &error);
+		if (error)
+			return;
+
+		rtw_write8(adapt, REG_BCN_CTRL, tmp & (~BIT(4)));
 
 		/*  To make sure that if there exists an adapter which would like to send beacon. */
 		/*  If exists, the origianl value of 0x422[6] will be 1, we should check this to */
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
index 78552303c990..c645d7fc8e8b 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
@@ -16,8 +16,12 @@ static void dm_CheckStatistics(struct adapter *Adapter)
 static void dm_InitGPIOSetting(struct adapter *Adapter)
 {
 	u8	tmp1byte;
+	int error;
+
+	tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG, &error);
+	if (error)
+		return;
 
-	tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
 	tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
 
 	rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 393969f51206..0a2c08a24ad8 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -13,10 +13,14 @@
 static void iol_mode_enable(struct adapter *padapter, u8 enable)
 {
 	u8 reg_0xf0 = 0;
+	int error;
 
 	if (enable) {
 		/* Enable initial offload */
-		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG, &error);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
 
 		if (!padapter->bFWReady) {
@@ -26,7 +30,10 @@ static void iol_mode_enable(struct adapter *padapter, u8 enable)
 
 	} else {
 		/* disable initial offload */
-		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG, &error);
+		if (error)
+			return;
+	
 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
 	}
 }
@@ -36,18 +43,28 @@ static s32 iol_execute(struct adapter *padapter, u8 control)
 	s32 status = _FAIL;
 	u8 reg_0x88 = 0;
 	u32 start = 0, passing_time = 0;
+	int error;
 
 	control = control & 0x0f;
-	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0, &error);
+	if (error)
+		return status;
+
 	rtw_write8(padapter, REG_HMEBOX_E0,  reg_0x88 | control);
 
 	start = jiffies;
-	while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
-	       (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
-		;
-	}
 
-	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+	do {
+		reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0, &error);
+		if (error)
+			return status;
+	} while (reg_0x88 & control &&
+	        (passing_time = rtw_get_passing_time_ms(start)) < 1000);
+
+	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0, &error);
+	if (error)
+		return status;
+
 	status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
 	if (reg_0x88 & control << 4)
 		status = _FAIL;
@@ -201,11 +218,15 @@ static void efuse_read_phymap_from_txpktbuf(
 	u16 len = 0, count = 0;
 	int i = 0;
 	u16 limit = *size;
+	int error;
 
 	u8 *pos = content;
 
-	if (bcnhead < 0) /* if not valid */
-		bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
+	if (bcnhead < 0) {	/* if not valid */
+		bcnhead = rtw_read8(adapter, REG_TDECTRL + 1, &error);
+		if (error)
+			return;
+	}
 
 	DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
 
@@ -218,22 +239,37 @@ static void efuse_read_phymap_from_txpktbuf(
 
 		rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
 		start = jiffies;
-		while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
+
+		reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG, &error);
+		if (error)
+			return;
+
+		while (!reg_0x143 &&
 		       (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
-			DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
+			DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106, &error));
 			rtw_usleep_os(100);
+
+			reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG, &error);
+			if (error)
+				return;
 		}
 
 		/* data from EEPROM needs to be in LE */
-		lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
-		hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));
+		lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &error));
+		if (error)
+			return;
+		hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &error));
+		if (error)
+			return;
 
 		if (i == 0) {
 			/* Although lenc is only used in a debug statement,
 			 * do not remove it as the rtw_read16() call consumes
 			 * 2 bytes from the EEPROM source.
 			 */
-			u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
+			u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &error);
+			if (error)
+				return;
 
 			len = le32_to_cpu(lo32) & 0x0000ffff;
 
@@ -342,6 +378,8 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 	u32 addr, rstatus, loop = 0;
 	u16 data_cnts = (data_len / 8) + 1;
 	u8 *pbuf = vzalloc(data_len + 10);
+	int error;
+
 	DBG_88E("###### %s ######\n", __func__);
 
 	rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
@@ -351,12 +389,22 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 			rtw_usleep_os(2);
 			loop = 0;
 			do {
-				rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24));
+				u32 tmp = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL, &error);
+
+				if (error)
+					break;
+
+				rstatus = (reg_140 = tmp & BIT(24));
 				if (rstatus) {
-					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
+					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L, &error);
+					if (error)
+						break;
+
 					memcpy(pbuf + (addr * 8), &fifo_data, 4);
 
-					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
+					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H, &error);
+					if (error)
+						break;
 					memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
 				}
 				rtw_usleep_os(2);
@@ -371,18 +419,25 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 static void _FWDownloadEnable(struct adapter *padapter, bool enable)
 {
 	u8 tmp;
+	int error;
 
 	if (enable) {
 		/*  MCU firmware download enable. */
-		tmp = rtw_read8(padapter, REG_MCUFWDL);
+		tmp = rtw_read8(padapter, REG_MCUFWDL, &error);
+		if (error)
+			return;
 		rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
 
 		/*  8051 reset */
-		tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
+		tmp = rtw_read8(padapter, REG_MCUFWDL + 2, &error);
+		if (error)
+			return;
 		rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
 	} else {
 		/*  MCU firmware download disable. */
-		tmp = rtw_read8(padapter, REG_MCUFWDL);
+		tmp = rtw_read8(padapter, REG_MCUFWDL, &error);
+		if (error)
+			return;
 		rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
 
 		/*  Reserved for fw extension. */
@@ -452,8 +507,14 @@ static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size
 {
 	u8 value8;
 	u8 u8Page = (u8)(page & 0x07);
+	int error;
+	u8 tmp;
 
-	value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
+	tmp = rtw_read8(padapter, REG_MCUFWDL + 2, &error);
+	if (error)
+		return _FAIL;
+
+	value8 = (tmp & 0xF8) | u8Page;
 	rtw_write8(padapter, REG_MCUFWDL + 2, value8);
 
 	return _BlockWrite(padapter, buffer, size);
@@ -493,8 +554,12 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
 void _8051Reset88E(struct adapter *padapter)
 {
 	u8 u1bTmp;
+	int error;
+
+	u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &error);
+	if (error)
+		return;
 
-	u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
 	rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2)));
 	rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2)));
 	DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
@@ -504,10 +569,13 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 {
 	u32	counter = 0;
 	u32	value32;
+	int error;
 
 	/*  polling CheckSum report */
 	do {
-		value32 = rtw_read32(padapter, REG_MCUFWDL);
+		value32 = rtw_read32(padapter, REG_MCUFWDL, &error);
+		if (error)
+			return _FAIL;
 		if (value32 & FWDL_ChkSum_rpt)
 			break;
 	} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -518,7 +586,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 	}
 	DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
 
-	value32 = rtw_read32(padapter, REG_MCUFWDL);
+	value32 = rtw_read32(padapter, REG_MCUFWDL, &error);
+	if (error)
+		return _FAIL;
+
 	value32 |= MCUFWDL_RDY;
 	value32 &= ~WINTINI_RDY;
 	rtw_write32(padapter, REG_MCUFWDL, value32);
@@ -528,7 +599,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 	/*  polling for FW ready */
 	counter = 0;
 	do {
-		value32 = rtw_read32(padapter, REG_MCUFWDL);
+		value32 = rtw_read32(padapter, REG_MCUFWDL, &error);
+		if (error)
+			return -FAIL;
+
 		if (value32 & WINTINI_RDY) {
 			DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
 			return _SUCCESS;
@@ -591,6 +665,8 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 	u8 *pFirmwareBuf;
 	u32 FirmwareLen;
 	static int log_version;
+	int error;
+	u8 tmp;
 
 	if (!dvobj->firmware.szFwBuffer)
 		rtStatus = load_firmware(&dvobj->firmware, device);
@@ -621,7 +697,11 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 
 	/*  Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
 	/*  or it will cause download Fw fail. 2010.02.01. by tynli. */
-	if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+	tmp = rtw_read8(padapter, REG_MCUFWDL, &error);
+	if (error)
+		return _FAIL;
+
+	if (tmp & RAM_DL_SEL) { /* 8051 RAM code */
 		rtw_write8(padapter, REG_MCUFWDL, 0x00);
 		_8051Reset88E(padapter);
 	}
@@ -629,8 +709,12 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 	_FWDownloadEnable(padapter, true);
 	fwdl_start_time = jiffies;
 	while (1) {
+		tmp = rtw_read8(padapter, REG_MCUFWDL, &error);
+		if (error)
+			return _FAIL;
+
 		/* reset the FWDL chksum */
-		rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
+		rtw_write8(padapter, REG_MCUFWDL, tmp | FWDL_ChkSum_rpt);
 
 		rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
 
@@ -715,25 +799,35 @@ hal_EfusePowerSwitch_RTL8188E(
 {
 	u8 tempval;
 	u16	tmpV16;
+	int error;
 
 	if (PwrState) {
 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
 
 		/*  1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
-		tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
+		tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &error);
+		if (error)
+			return;
+
 		if (!(tmpV16 & PWC_EV12V)) {
 			tmpV16 |= PWC_EV12V;
 			rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
 		}
 		/*  Reset: 0x0000h[28], default valid */
-		tmpV16 =  rtw_read16(pAdapter, REG_SYS_FUNC_EN);
+		tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &error);
+		if (error)
+			return;
+
 		if (!(tmpV16 & FEN_ELDR)) {
 			tmpV16 |= FEN_ELDR;
 			rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
 		}
 
 		/*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
-		tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
+		tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR, &error);
+		if (error)
+			return;
+
 		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
 			tmpV16 |= (LOADER_CLK_EN | ANA8M);
 			rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
@@ -741,7 +835,9 @@ hal_EfusePowerSwitch_RTL8188E(
 
 		if (bWrite) {
 			/*  Enable LDO 2.5V before read/write action */
-			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3, &error);
+			if (error)
+				return;
 			tempval &= 0x0F;
 			tempval |= (VOLTAGE_V25 << 4);
 			rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
@@ -751,7 +847,9 @@ hal_EfusePowerSwitch_RTL8188E(
 
 		if (bWrite) {
 			/*  Disable LDO 2.5V after read/write action */
-			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3, &error);
+			if (error)
+				return;
 			rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
 		}
 	}
@@ -1692,12 +1790,15 @@ static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8
 static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
 {
 	u32				value32;
-	struct HAL_VERSION		ChipVersion;
+	struct HAL_VERSION		ChipVersion = { };
 	struct hal_data_8188e	*pHalData;
+	int error;
 
 	pHalData = GET_HAL_DATA(padapter);
 
-	value32 = rtw_read32(padapter, REG_SYS_CFG);
+	value32 = rtw_read32(padapter, REG_SYS_CFG, &error);
+	if (error)
+		return ChipVersion;
 	ChipVersion.ICType = CHIP_8188E;
 	ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
 
@@ -1784,12 +1885,23 @@ void rtl8188e_stop_thread(struct adapter *padapter)
 
 static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
 {
+	int error;
+	u8 tmp;
+
 	if (enable) {
 		DBG_88E("Enable notch filter\n");
-		rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
+		tmp = rtw_read8(adapter, rOFDM0_RxDSP + 1, &error);
+		if (error)
+			return;
+
+		rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp | BIT(1));
 	} else {
 		DBG_88E("Disable notch filter\n");
-		rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
+		tmp = rtw_read8(adapter, rOFDM0_RxDSP + 1, &error);
+		if (error)
+			return;
+
+		rtw_write8(adapter, rOFDM0_RxDSP + 1, TCA_DUMP_FLAGS_TERSE & ~BIT(1));
 	}
 }
 void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
@@ -1845,8 +1957,12 @@ u8 GetEEPROMSize8188E(struct adapter *padapter)
 {
 	u8 size = 0;
 	u32	cr;
+	int error;
+
+	cr = rtw_read16(padapter, REG_9346CR, &error);
+	if (error)
+		return size;
 
-	cr = rtw_read16(padapter, REG_9346CR);
 	/*  6: EEPROM used is 93C46, 4: boot from E-Fuse. */
 	size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
 
@@ -1866,12 +1982,16 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
 	s32	count = 0;
 	u32	value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
 	u16	LLTReg = REG_LLT_INIT;
+	int error;
 
 	rtw_write32(padapter, LLTReg, value);
 
 	/* polling */
 	do {
-		value = rtw_read32(padapter, LLTReg);
+		value = rtw_read32(padapter, LLTReg, &error);
+		if (error)
+			return _FAIL;
+
 		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
 			break;
 
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 30a9dca8f453..6264778ed9c3 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -75,8 +75,12 @@ rtl8188e_PHY_QueryBBReg(
 	)
 {
 	u32 ReturnValue = 0, OriginalValue, BitShift;
+	int error;
+
+	OriginalValue = rtw_read32(Adapter, RegAddr, &error);
+	if (error)
+		return ReturnValue;
 
-	OriginalValue = rtw_read32(Adapter, RegAddr);
 	BitShift = phy_CalculateBitShift(BitMask);
 	ReturnValue = (OriginalValue & BitMask) >> BitShift;
 	return ReturnValue;
@@ -103,9 +107,12 @@ rtl8188e_PHY_QueryBBReg(
 void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
 {
 	u32 OriginalValue, BitShift;
+	int error;
 
 	if (BitMask != bMaskDWord) { /* if not "double word" write */
-		OriginalValue = rtw_read32(Adapter, RegAddr);
+		OriginalValue = rtw_read32(Adapter, RegAddr, &error);
+		if (error)
+			return;
 		BitShift = phy_CalculateBitShift(BitMask);
 		Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
 	}
@@ -577,11 +584,15 @@ PHY_BBConfig8188E(
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(Adapter);
 	u32 RegVal;
 	u8 CrystalCap;
+	int error;
 
 	phy_InitBBRFRegisterDefinition(Adapter);
 
 	/*  Enable BB and RF */
-	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN, &error);
+	if (error)
+		return -FAIL;
+
 	rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
 
 	/*  20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
@@ -960,6 +971,7 @@ _PHY_SetBWMode92C(
 	struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
 	u8 regBwOpMode;
 	u8 regRRSR_RSC;
+	int error;
 
 	if (pHalData->rf_chip == RF_PSEUDO_11N)
 		return;
@@ -975,8 +987,12 @@ _PHY_SetBWMode92C(
 	/* 3<1>Set MAC register */
 	/* 3 */
 
-	regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
-	regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2);
+	regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE, &error);
+	if (error)
+		return;
+	regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2, &error);
+	if (error)
+		return;
 
 	switch (pHalData->CurrentChannelBW) {
 	case HT_CHANNEL_WIDTH_20:
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 16fa249e35d3..1bb86629574d 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -14,13 +14,16 @@ void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
 {
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+	int error;
 	unsigned long current_time;
 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
 	unsigned int diff_time;
 	u32 txdma_status;
 
-	txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
+	txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS, &error);
+	if (error)
+		return;
+
 	if (txdma_status != 0x00) {
 		DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
 		rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
@@ -49,12 +52,21 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
 {
 	u32 rx_dma_status = 0;
 	u8 fw_status = 0;
-	rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
+	int error;
+
+	rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS, &error);
+	if (error)
+		return;
+
 	if (rx_dma_status != 0x00) {
 		DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
 		rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
 	}
-	fw_status = rtw_read8(padapter, REG_FMETHR);
+
+	fw_status = rtw_read8(padapter, REG_FMETHR, &error);
+	if (error)
+		return;
+
 	if (fw_status != 0x00) {
 		if (fw_status == 1)
 			DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status);
diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_led.c b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
index 452d4bb87aba..2467adb51f7d 100644
--- a/drivers/staging/r8188eu/hal/rtl8188eu_led.c
+++ b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
@@ -14,10 +14,15 @@
 void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
 {
 	u8	LedCfg;
+	int error;
 
 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
 		return;
-	LedCfg = rtw_read8(padapter, REG_LEDCFG2);
+
+	LedCfg = rtw_read8(padapter, REG_LEDCFG2, &error);
+	if (error)
+		return;
+
 	switch (pLed->LedPin) {
 	case LED_PIN_LED0:
 		rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /*  SW control led0 on. */
@@ -37,11 +42,14 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
 {
 	u8	LedCfg;
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
+	int error;
 
 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
 		goto exit;
 
-	LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+	LedCfg = rtw_read8(padapter, REG_LEDCFG2, &error);/* 0x4E */
+	if (error)
+		return;
 
 	switch (pLed->LedPin) {
 	case LED_PIN_LED0:
@@ -49,7 +57,10 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
 			/*  Open-drain arrangement for controlling the LED) */
 			LedCfg &= 0x90; /*  Set to software control. */
 			rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
-			LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+			LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &error);
+			if (error)
+				return;
+
 			LedCfg &= 0xFE;
 			rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
 		} else {
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 5cdabf43d4fd..73ef2e0ead19 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -90,6 +90,8 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
 	u16 value16;
 	/*  HW Power on sequence */
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(adapt);
+	int error;
+	
 	if (haldata->bMacPwrCtrlOn)
 		return _SUCCESS;
 
@@ -103,7 +105,10 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
 	rtw_write16(adapt, REG_CR, 0x00);  /* suggseted by zhouzhou, by page, 20111230 */
 
 		/*  Enable MAC DMA/WMAC/SCHEDULE/SEC block */
-	value16 = rtw_read16(adapt, REG_CR);
+	value16 = rtw_read16(adapt, REG_CR, &error);
+	if (error)
+		return _FAIL;
+
 	value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
 				| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
 	/*  for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
@@ -120,6 +125,7 @@ static void _InitInterrupt(struct adapter *Adapter)
 	u32 imr, imr_ex;
 	u8  usb_opt;
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
+	int error;
 
 	/* HISR write one to clear */
 	rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
@@ -135,7 +141,9 @@ static void _InitInterrupt(struct adapter *Adapter)
 	/*  REG_USB_SPECIAL_OPTION - BIT(4) */
 	/*  0; Use interrupt endpoint to upload interrupt pkt */
 	/*  1; Use bulk endpoint to upload interrupt pkt, */
-	usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+	usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &error);
+	if (error)
+		return;
 
 	if (!adapter_to_dvobj(Adapter)->ishighspeed)
 		usb_opt = usb_opt & (~INT_BULK_SEL);
@@ -204,7 +212,14 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
 				       u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
 				       u16 hiQ)
 {
-	u16 value16	= (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+	u16 value16;
+	int error;
+
+	value16 = rtw_read16(Adapter, REG_TRXDMA_CTRL, &error);
+	if (error)
+		return;
+
+	value16 &= 0x7;
 
 	value16 |= _TXDMA_BEQ_MAP(beQ)	| _TXDMA_BKQ_MAP(bkQ) |
 		   _TXDMA_VIQ_MAP(viQ)	| _TXDMA_VOQ_MAP(voQ) |
@@ -323,8 +338,11 @@ static void _InitQueuePriority(struct adapter *Adapter)
 static void _InitNetworkType(struct adapter *Adapter)
 {
 	u32 value32;
+	int error;
 
-	value32 = rtw_read32(Adapter, REG_CR);
+	value32 = rtw_read32(Adapter, REG_CR, &error);
+	if (error)
+		return;
 	/*  TODO: use the other function to set network type */
 	value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
 
@@ -366,9 +384,13 @@ static void _InitAdaptiveCtrl(struct adapter *Adapter)
 {
 	u16 value16;
 	u32 value32;
+	int error;
 
 	/*  Response Rate Set */
-	value32 = rtw_read32(Adapter, REG_RRSR);
+	value32 = rtw_read32(Adapter, REG_RRSR, &error);
+	if (error)
+		return;
+
 	value32 &= ~RATE_BITMAP_ALL;
 	value32 |= RATE_RRSR_CCK_ONLY_1M;
 	rtw_write32(Adapter, REG_RRSR, value32);
@@ -435,8 +457,11 @@ static void _InitRxSetting(struct adapter *Adapter)
 static void _InitRetryFunction(struct adapter *Adapter)
 {
 	u8 value8;
+	int error;
 
-	value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
+	value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL, &error);
+	if (error)
+		return;
 	value8 |= EN_AMPDU_RTY_NEW;
 	rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
 
@@ -463,12 +488,16 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	u32 value32;
+	int error;
 
 	if (Adapter->registrypriv.wifi_spec)
 		haldata->UsbTxAggMode = false;
 
 	if (haldata->UsbTxAggMode) {
-		value32 = rtw_read32(Adapter, REG_TDECTRL);
+		value32 = rtw_read32(Adapter, REG_TDECTRL, &error);
+		if (error)
+			return;
+
 		value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
 		value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
 
@@ -499,9 +528,14 @@ usb_AggSettingRxUpdate(
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	u8 valueDMA;
 	u8 valueUSB;
+	int error;
 
-	valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
-	valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+	valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL, &error);
+	if (error)
+		return;
+	valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &error);
+	if (error)
+		return;
 
 	switch (haldata->UsbRxAggMode) {
 	case USB_RX_AGG_DMA:
@@ -589,6 +623,7 @@ static void _InitOperationMode(struct adapter *Adapter)
 static void _InitBeaconParameters(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
+	int error;
 
 	rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
 
@@ -601,11 +636,11 @@ static void _InitBeaconParameters(struct adapter *Adapter)
 	/*  beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
 	rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
 
-	haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL);
-	haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE);
-	haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
-	haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2);
-	haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1);
+	haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+	haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE, &error);
+	haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2, &error);
+	haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2, &error);
+	haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1, &error);
 }
 
 static void _BeaconFunctionEnable(struct adapter *Adapter,
@@ -631,12 +666,18 @@ enum {
 static void _InitAntenna_Selection(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(Adapter);
+	int error;
+	u32 tmp;
 
 	if (haldata->AntDivCfg == 0)
 		return;
 	DBG_88E("==>  %s ....\n", __func__);
 
-	rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23));
+	tmp = rtw_read32(Adapter, REG_LEDCFG0, &error);
+	if (error)
+		return;
+
+	rtw_write32(Adapter, REG_LEDCFG0, tmp | BIT(23));
 	PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
 
 	if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
@@ -665,14 +706,22 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt)
 {
 	u8 val8;
 	enum rt_rf_power_state rfpowerstate = rf_off;
+	int error;
 
 	if (adapt->pwrctrlpriv.bHWPowerdown) {
-		val8 = rtw_read8(adapt, REG_HSISR);
+		val8 = rtw_read8(adapt, REG_HSISR, &error);
+		if (error)
+			return rfpowerstate;
 		DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8);
 		rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on;
 	} else { /*  rf on/off */
-		rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3)));
-		val8 = rtw_read8(adapt, REG_GPIO_IO_SEL);
+		val8 = rtw_read8(adapt, REG_MAC_PINMUX_CFG, &error);
+		if (error)
+			return rfpowerstate;
+		rtw_write8(adapt, REG_MAC_PINMUX_CFG, val8 & ~(BIT(3)));
+		val8 = rtw_read8(adapt, REG_GPIO_IO_SEL, &error);
+		if (error)
+			return rfpowerstate;
 		DBG_88E("GPIO_IN=%02x\n", val8);
 		rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
 	}
@@ -683,12 +732,14 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 {
 	u8 value8 = 0;
 	u16  value16;
+	u32 value32;
 	u8 txpktbuf_bndy;
 	u32 status = _SUCCESS;
 	struct hal_data_8188e		*haldata = GET_HAL_DATA(Adapter);
 	struct pwrctrl_priv		*pwrctrlpriv = &Adapter->pwrctrlpriv;
 	struct registry_priv	*pregistrypriv = &Adapter->registrypriv;
 	u32 init_start_time = jiffies;
+	int error;
 
 	#define HAL_INIT_PROFILE_TAG(stage) do {} while (0)
 
@@ -826,7 +877,12 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	/*  Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
 	/*  */
 	/*  Enable MACTXEN/MACRXEN block */
-	value16 = rtw_read16(Adapter, REG_CR);
+	value16 = rtw_read16(Adapter, REG_CR, &error);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
+
 	value16 |= (MACTXEN | MACRXEN);
 	rtw_write8(Adapter, REG_CR, value16);
 
@@ -835,7 +891,11 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 
 	/* Enable TX Report */
 	/* Enable Tx Report Timer */
-	value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+	value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL, &error);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
 	rtw_write8(Adapter,  REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0)));
 	/* Set MAX RPT MACID */
 	rtw_write8(Adapter,  REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
@@ -910,7 +970,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 		rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
 
 		/* enable tx DMA to drop the redundate data of packet */
-		rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+		value16 = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &error);
+		if (error) {
+			status = _FAIL;
+			goto exit;
+		}
+
+		rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (value16 | DROP_DATA_EN));
 
 		HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
 		/*  2010/08/26 MH Merge from 8192CE. */
@@ -936,7 +1002,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	rtw_write8(Adapter, REG_USB_HRPWM, 0);
 
 	/* ack for xmit mgmt frames. */
-	rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
+	value32 = rtw_read32(Adapter, REG_FWHW_TXQ_CTRL, &error);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
+
+	rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, value32 | BIT(12));
 
 exit:
 	HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
@@ -962,9 +1034,13 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 {
 	u8 val8;
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(Adapter);
+	int error;
 
 	/* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
-	val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+	val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL, &error);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1)));
 
 	/*  stop rx */
@@ -975,10 +1051,16 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 
 	/*  2. 0x1F[7:0] = 0		turn off RF */
 
-	val8 = rtw_read8(Adapter, REG_MCUFWDL);
+	val8 = rtw_read8(Adapter, REG_MCUFWDL, &error);
+	if (error)
+		return;
+
 	if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
 		/*  Reset MCU 0x2[10]=0. */
-		val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1);
+		val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1, &error);
+		if (error)
+			return;
+
 		val8 &= ~BIT(2);	/*  0x2[10], FEN_CPUEN */
 		rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
 	}
@@ -988,26 +1070,44 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 
 	/* YJ,add,111212 */
 	/* Disable 32k */
-	val8 = rtw_read8(Adapter, REG_32K_CTRL);
+	val8 = rtw_read8(Adapter, REG_32K_CTRL, &error);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0)));
 
 	/*  Card disable power action flow */
 	HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW);
 
 	/*  Reset MCU IO Wrapper */
-	val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+	val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1, &error);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3))));
-	val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+	val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1, &error);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3));
 
 	/* YJ,test add, 111207. For Power Consumption. */
-	val8 = rtw_read8(Adapter, GPIO_IN);
+	val8 = rtw_read8(Adapter, GPIO_IN, &error);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, GPIO_OUT, val8);
 	rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
 
-	val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
+	val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL, &error);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
-	val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1);
+	val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1, &error);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */
 	rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
 	haldata->bMacPwrCtrlOn = false;
@@ -1181,9 +1281,13 @@ static void _ReadPROMContent(
 {
 	struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(Adapter);
 	u8 eeValue;
+	int error;
 
 	/* check system boot selection */
-	eeValue = rtw_read8(Adapter, REG_9346CR);
+	eeValue = rtw_read8(Adapter, REG_9346CR, &error);
+	if (error)
+		return;
+
 	eeprom->EepromOrEfuse		= (eeValue & BOOT_FROM_EEPROM) ? true : false;
 	eeprom->bautoload_fail_flag	= (eeValue & EEPROM_EN) ? false : true;
 
@@ -1262,12 +1366,23 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
 {
 	u8 val8;
 	u8 mode = *((u8 *)val);
+	u8 tmp;
+	int error;
 
 	/*  disable Port0 TSF update */
-	rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+	tmp = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+	if (error)
+		return;
+
+	rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
 
 	/*  set net_type */
-	val8 = rtw_read8(Adapter, MSR) & 0x0c;
+	val8 = rtw_read8(Adapter, MSR, &error);
+	if (error)
+		return;
+
+	val8 &= 0x0c;
+
 	val8 |= mode;
 	rtw_write8(Adapter, MSR, val8);
 
@@ -1304,14 +1419,22 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
 		rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
 
 		/* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
-		rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+		tmp = rtw_read8(Adapter, REG_MBID_NUM, &error);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, REG_MBID_NUM, tmp | BIT(3) | BIT(4));
 
 		/* enable BCN0 Function for if1 */
 		/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
 		rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
 
 		/* dis BCN1 ATIM  WND if if2 is station */
-		rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+		tmp = rtw_read8(Adapter, REG_BCN_CTRL_1, &error);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, REG_BCN_CTRL_1, tmp | BIT(0));
 	}
 }
 
@@ -1340,13 +1463,20 @@ static void hw_var_set_bssid(struct adapter *Adapter, u8 variable, u8 *val)
 static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
 {
 	u32 bcn_ctrl_reg;
+	u8 tmp;
+	int error;
 
 	bcn_ctrl_reg = REG_BCN_CTRL;
 
-	if (*((u8 *)val))
+	if (*((u8 *)val)) {
 		rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
-	else
-		rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+	} else {
+		tmp = rtw_read8(Adapter, bcn_ctrl_reg, &error);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, bcn_ctrl_reg, tmp & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+	}
 }
 
 static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1354,13 +1484,21 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	struct dm_priv	*pdmpriv = &haldata->dmpriv;
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+	int error;
+	u32 val32;
+	u8 val8;
 
 	switch (variable) {
 	case HW_VAR_MEDIA_STATUS:
 		{
 			u8 val8;
 
-			val8 = rtw_read8(Adapter, MSR) & 0x0c;
+			val8 = rtw_read8(Adapter, MSR, &error);
+			if (error)
+				return;
+
+			val8 &= 0x0c;
+
 			val8 |= *((u8 *)val);
 			rtw_write8(Adapter, MSR, val8);
 		}
@@ -1369,7 +1507,12 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			u8 val8;
 
-			val8 = rtw_read8(Adapter, MSR) & 0x03;
+			val8 = rtw_read8(Adapter, MSR, &error);
+			if (error)
+				return;
+
+			val8 &= 0x03;
+	
 			val8 |= *((u8 *)val) << 2;
 			rtw_write8(Adapter, MSR, val8);
 		}
@@ -1407,7 +1550,12 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			/*  Set RRSR rate table. */
 			rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
 			rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
-			rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0);
+
+			val8 = rtw_read8(Adapter, REG_RRSR + 2, &error);
+			if (error)
+				return;
+
+			rtw_write8(Adapter, REG_RRSR + 2, val8 & 0xf0);
 
 			/*  Set RTS initial rate */
 			while (BrateCfg > 0x1) {
@@ -1437,13 +1585,19 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				StopTxBeacon(Adapter);
 
 			/* disable related TSF function */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3)));
+			val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+			if (error)
+				return;
+			rtw_write8(Adapter, REG_BCN_CTRL, val8 & (~BIT(3)));
 
 			rtw_write32(Adapter, REG_TSFTR, tsf);
 			rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
 
 			/* enable related TSF function */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3));
+			val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+			if (error)
+				return;
+			rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(3));
 
 			if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
 				ResumeTxBeacon(Adapter);
@@ -1451,11 +1605,17 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		break;
 	case HW_VAR_CHECK_BSSID:
 		if (*((u8 *)val)) {
-			rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+			val32 = rtw_read32(Adapter, REG_RCR, &error);
+			if (error)
+				return;
+
+			rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 		} else {
-			u32 val32;
 
-			val32 = rtw_read32(Adapter, REG_RCR);
+			val32 = rtw_read32(Adapter, REG_RCR, &error);
+
+			if (error)
+				return;
 
 			val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 
@@ -1471,19 +1631,29 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
 
 		/* disable update TSF */
-		rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+		val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+		if (error)
+			return;
+		rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(4));
 		break;
 	case HW_VAR_MLME_SITESURVEY:
 		if (*((u8 *)val)) { /* under sitesurvey */
 			/* config RCR to receive different BSSID & not to receive data frame */
-			u32 v = rtw_read32(Adapter, REG_RCR);
+			u32 v = rtw_read32(Adapter, REG_RCR, &error);
+
+			if (error)
+				return;
+
 			v &= ~(RCR_CBSSID_BCN);
 			rtw_write32(Adapter, REG_RCR, v);
 			/* reject all data frame */
 			rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
 
 			/* disable update TSF */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+			val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+			if (error)
+				return;
+			rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(4));
 		} else { /* sitesurvey done */
 			struct mlme_ext_priv	*pmlmeext = &Adapter->mlmeextpriv;
 			struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
@@ -1494,21 +1664,39 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+				if (error)
+					return;
+				rtw_write8(Adapter, REG_BCN_CTRL, val8 & (~BIT(4)));
 			} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+				if (error)
+					return;
+				rtw_write8(Adapter, REG_BCN_CTRL, val8 & (~BIT(4)));
 			}
 			if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
-				rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+				val32 = rtw_read32(Adapter, REG_RCR, &error);
+				if (error)
+					return;
+
+				rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_BCN);
 			} else {
 				if (Adapter->in_cta_test) {
-					u32 v = rtw_read32(Adapter, REG_RCR);
+					u32 v = rtw_read32(Adapter, REG_RCR, &error);
+
+					if (error)
+						return;
+
 					v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 					rtw_write32(Adapter, REG_RCR, v);
 				} else {
-					rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+					val32 = rtw_read32(Adapter, REG_RCR, &error);
+					if (error)
+						return;
+
+					rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_BCN);
 				}
 			}
 		}
@@ -1524,11 +1712,20 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 
 				if (Adapter->in_cta_test) {
-					u32 v = rtw_read32(Adapter, REG_RCR);
+					u32 v = rtw_read32(Adapter, REG_RCR, &error);
+
+					if (error)
+						return;
+
 					v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 					rtw_write32(Adapter, REG_RCR, v);
 				} else {
-					rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+					val32 = rtw_read32(Adapter, REG_RCR, &error);
+
+					if (error)
+						return;
+
+					rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 				}
 
 				if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
@@ -1541,7 +1738,10 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			} else if (type == 2) {
 				/* sta add event call back */
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				val8 = rtw_read8(Adapter, REG_BCN_CTRL, &error);
+				if (error)
+					return;
+				rtw_write8(Adapter, REG_BCN_CTRL, val8 & (~BIT(4)));
 
 				if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
 					RetryLimit = 0x7;
@@ -1671,7 +1871,10 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	case HW_VAR_ACM_CTRL:
 		{
 			u8 acm_ctrl = *((u8 *)val);
-			u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL);
+			u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL, &error);
+
+			if (error)
+				return;
 
 			if (acm_ctrl > 1)
 				AcmCtrl = AcmCtrl | 0x1;
@@ -1719,7 +1922,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				}
 				if (MinSpacingToSet < SecMinSpace)
 					MinSpacingToSet = SecMinSpace;
-				rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
+
+				val8 = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &error);
+				if (error)
+					return;
+				rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (val8 & 0xf8) | MinSpacingToSet);
 			}
 		}
 		break;
@@ -1826,18 +2033,31 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
 			u8 trycnt = 100;
+			u32 tmp;
 
 			/* pause tx */
 			rtw_write8(Adapter, REG_TXPAUSE, 0xff);
 
 			/* keep sn */
-			Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
+			tmp = rtw_read16(Adapter, REG_NQOS_SEQ, &error);
+			if (error)
+				return;
+
+			Adapter->xmitpriv.nqos_ssn = (u16) tmp;
 
 			if (!pwrpriv->bkeepfwalive) {
 				/* RX DMA stop */
-				rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+				tmp = rtw_read32(Adapter, REG_RXPKT_NUM, &error);
+				if (error)
+					return;
+
+				rtw_write32(Adapter, REG_RXPKT_NUM, tmp | RW_RELEASE_EN);
 				do {
-					if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
+					tmp = rtw_read32(Adapter, REG_RXPKT_NUM, &error);
+					if (error)
+						continue;
+
+					if (!(tmp & RXDMA_IDLE))
 						break;
 				} while (trycnt--);
 				if (trycnt == 0)
@@ -1868,7 +2088,10 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		break;
 	case HW_VAR_BCN_VALID:
 		/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
-		rtw_write8(Adapter, REG_TDECTRL + 2, rtw_read8(Adapter, REG_TDECTRL + 2) | BIT(0));
+		val8 = rtw_read8(Adapter, REG_TDECTRL + 2, &error);
+		if (error)
+			return;
+		rtw_write8(Adapter, REG_TDECTRL + 2, val8 | BIT(0));
 		break;
 	default:
 		break;
@@ -1880,17 +2103,26 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+	int error;
+	u32 tmp;
 
 	switch (variable) {
 	case HW_VAR_BASIC_RATE:
 		*((u16 *)(val)) = haldata->BasicRateSet;
 		fallthrough;
 	case HW_VAR_TXPAUSE:
-		val[0] = rtw_read8(Adapter, REG_TXPAUSE);
+		tmp = rtw_read8(Adapter, REG_TXPAUSE, &error);
+		if (error)
+			return;
+
+		val[0] = tmp;
 		break;
 	case HW_VAR_BCN_VALID:
 		/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */
-		val[0] = (BIT(0) & rtw_read8(Adapter, REG_TDECTRL + 2)) ? true : false;
+		tmp = rtw_read8(Adapter, REG_TDECTRL + 2, &error);
+		if (error)
+			return;
+		val[0] = (BIT(0) & tmp) ? true : false;
 		break;
 	case HW_VAR_DM_FLAG:
 		val[0] = podmpriv->SupportAbility;
@@ -1907,7 +2139,9 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				val[0] = true;
 			} else {
 				u32 valRCR;
-				valRCR = rtw_read32(Adapter, REG_RCR);
+				valRCR = rtw_read32(Adapter, REG_RCR, &error);
+				if (error)
+					return;
 				valRCR &= 0x00070000;
 				if (valRCR)
 					val[0] = false;
@@ -1926,7 +2160,11 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		*val = haldata->bMacPwrCtrlOn;
 		break;
 	case HW_VAR_CHK_HI_QUEUE_EMPTY:
-		*val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false;
+		tmp = rtw_read32(Adapter, REG_HGQ_INFORMATION, &error);
+		if (error)
+			return;
+
+		*val = ((tmp & 0x0000ff00) == 0) ? true : false;
 		break;
 	default:
 		break;
@@ -2041,6 +2279,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
 		{
 			u8 dm_func = *((u8 *)pValue);
 			struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+			int error;
 
 			if (dm_func == 0) { /* disable all dynamic func */
 				podmpriv->SupportAbility = DYNAMIC_FUNC_DISABLE;
@@ -2058,7 +2297,12 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
 			} else if (dm_func == 6) {/* turn on all dynamic func */
 				if (!(podmpriv->SupportAbility  & DYNAMIC_BB_DIG)) {
 					struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
-					pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50);
+					u8 tmp = rtw_read8(Adapter, 0xc50, &error);
+					
+					if (error)
+						return _FAIL;
+					
+					pDigTable->CurIGValue = tmp;
 				}
 				podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
 				DBG_88E("==> Turn on all dynamic function...\n");
@@ -2168,6 +2412,8 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 	struct mlme_ext_priv	*pmlmeext = &adapt->mlmeextpriv;
 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
 	u32 bcn_ctrl_reg			= REG_BCN_CTRL;
+	int error;
+	u8 tmp;
 	/* reset TSF, enable update TSF, correcting TSF On Beacon */
 
 	/* BCN interval */
@@ -2178,7 +2424,9 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 
 	rtw_write8(adapt, REG_SLOT, 0x09);
 
-	value32 = rtw_read32(adapt, REG_TCR);
+	value32 = rtw_read32(adapt, REG_TCR, &error);
+	if (error)
+		return;
 	value32 &= ~TSFRST;
 	rtw_write32(adapt,  REG_TCR, value32);
 
@@ -2193,7 +2441,11 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 
 	ResumeTxBeacon(adapt);
 
-	rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1));
+	tmp = rtw_read8(adapt, bcn_ctrl_reg, &error);
+	if (error)
+		return;
+
+	rtw_write8(adapt, bcn_ctrl_reg, tmp | BIT(1));
 }
 
 static void rtl8188eu_init_default_value(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 953fa05dc30c..980af6c02be5 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -101,29 +101,31 @@ static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata,
 	return status;
 }
 
-static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr, int *error)
 {
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
 	u8 data = 0;
+	int res;
 
-
+	if (unlikely(!error))
+		WARN_ON_ONCE("r8188eu: Reading w/o error checking is bad idea\n");
 
 	requesttype = 0x01;/* read_in */
 
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 1;
 
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
-
-
+	res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	if (likely(error))
+		*error = res < 0? res: 0;
 
 	return data;
 
 }
 
-static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr, int *error)
 {
 	u8 requesttype;
 	u16 wvalue;
@@ -138,7 +140,7 @@ static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
 	return (u16)(le32_to_cpu(data) & 0xffff);
 }
 
-static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr, int *error)
 {
 	u8 requesttype;
 	u16 wvalue;
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index f1b3074fa075..7933c267b130 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -85,9 +85,9 @@ struct intf_hdl;
 struct io_queue;
 
 struct _io_ops {
-	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
-	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
-	u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr, int *error);
+	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr, int *error);
+	u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr, int *error);
 	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
 	int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
 	int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
@@ -248,9 +248,9 @@ void unregister_intf_hdl(struct intf_hdl *pintfhdl);
 void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 
-u8 _rtw_read8(struct adapter *adapter, u32 addr);
-u16 _rtw_read16(struct adapter *adapter, u32 addr);
-u32 _rtw_read32(struct adapter *adapter, u32 addr);
+u8 _rtw_read8(struct adapter *adapter, u32 addr, int *error);
+u16 _rtw_read16(struct adapter *adapter, u32 addr, int *error);
+u32 _rtw_read32(struct adapter *adapter, u32 addr, int *error);
 void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_read_port_cancel(struct adapter *adapter);
@@ -270,9 +270,9 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
 			     u8 *pmem, int timeout_ms);
 void _rtw_write_port_cancel(struct adapter *adapter);
 
-#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr))
-#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
-#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
+#define rtw_read8(adapter, addr, err) _rtw_read8((adapter), (addr), (err))
+#define rtw_read16(adapter, addr, err) _rtw_read16((adapter), (addr), (err))
+#define rtw_read32(adapter, addr, err) _rtw_read32((adapter), (addr), (err))
 #define rtw_read_mem(adapter, addr, cnt, mem)				\
 	_rtw_read_mem((adapter), (addr), (cnt), (mem))
 #define rtw_read_port(adapter, addr, cnt, mem)				\
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index ab4a9200f079..f5ec1daf1c30 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2074,6 +2074,7 @@ static int rtw_wx_read32(struct net_device *dev,
 	u32 data32;
 	u32 bytes;
 	u8 *ptmp;
+	int error;
 
 	padapter = (struct adapter *)rtw_netdev_priv(dev);
 	p = &wrqu->data;
@@ -2093,15 +2094,21 @@ static int rtw_wx_read32(struct net_device *dev,
 
 	switch (bytes) {
 	case 1:
-		data32 = rtw_read8(padapter, addr);
+		data32 = rtw_read8(padapter, addr, &error);
+		if (error)
+			goto end;
 		sprintf(extra, "0x%02X", data32);
 		break;
 	case 2:
-		data32 = rtw_read16(padapter, addr);
+		data32 = rtw_read16(padapter, addr, &error);
+		if (error)
+			goto end;
 		sprintf(extra, "0x%04X", data32);
 		break;
 	case 4:
-		data32 = rtw_read32(padapter, addr);
+		data32 = rtw_read32(padapter, addr, &error);
+		if (error)
+			goto end;
 		sprintf(extra, "0x%08X", data32);
 		break;
 	default:
@@ -2110,8 +2117,9 @@ static int rtw_wx_read32(struct net_device *dev,
 	}
 	DBG_88E(KERN_INFO "%s: addr = 0x%08X data =%s\n", __func__, addr, extra);
 
+end:
 	kfree(ptmp);
-	return 0;
+	return error;
 }
 
 static int rtw_wx_write32(struct net_device *dev,
@@ -2251,6 +2259,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 	u8 path;
 	u8 offset;
 	u32 value;
+	int error;
 
 	DBG_88E("%s\n", __func__);
 
@@ -2262,13 +2271,13 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 		RegRWStruct = (struct mp_rw_reg *)pdata;
 		switch (RegRWStruct->width) {
 		case 1:
-			RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
+			RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset, &error);
 			break;
 		case 2:
-			RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
+			RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset, &error);
 			break;
 		case 4:
-			RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
+			RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset, &error);
 			break;
 		default:
 			break;
@@ -3815,12 +3824,20 @@ static int rtw_cta_test_start(struct net_device *dev,
 		padapter->in_cta_test = 0;
 
 	if (padapter->in_cta_test) {
-		u32 v = rtw_read32(padapter, REG_RCR);
+		u32 v = rtw_read32(padapter, REG_RCR, &ret);
+
+		if (ret)
+			return ret;
+
 		v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 		rtw_write32(padapter, REG_RCR, v);
 		DBG_88E("enable RCR_ADF\n");
 	} else {
-		u32 v = rtw_read32(padapter, REG_RCR);
+		u32 v = rtw_read32(padapter, REG_RCR, &ret);
+
+		if (ret)
+			return ret;
+
 		v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/*  RCR_ADF */
 		rtw_write32(padapter, REG_RCR, v);
 		DBG_88E("disable RCR_ADF\n");
@@ -3890,18 +3907,19 @@ static int rtw_rereg_nd_name(struct net_device *dev,
 static void mac_reg_dump(struct adapter *padapter)
 {
 	int i, j = 1;
+	int error;
 	pr_info("\n ======= MAC REG =======\n");
 	for (i = 0x0; i < 0x300; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+		pr_info(" 0x%08x ", rtw_read32(padapter, i, &error));
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
 	for (i = 0x400; i < 0x800; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+		pr_info(" 0x%08x ", rtw_read32(padapter, i, &error));
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
@@ -3910,12 +3928,13 @@ static void mac_reg_dump(struct adapter *padapter)
 static void bb_reg_dump(struct adapter *padapter)
 {
 	int i, j = 1;
+	int error;
 	pr_info("\n ======= BB REG =======\n");
 	for (i = 0x800; i < 0x1000; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
 
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+		pr_info(" 0x%08x ", rtw_read32(padapter, i, &error));
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
@@ -3964,6 +3983,8 @@ static int rtw_dbg_port(struct net_device *dev,
 	struct security_priv *psecuritypriv = &padapter->securitypriv;
 	struct wlan_network *cur_network = &pmlmepriv->cur_network;
 	struct sta_priv *pstapriv = &padapter->stapriv;
+	int error;
+	u32 tmp;
 
 	pdata = (u32 *)&wrqu->data;
 
@@ -3978,13 +3999,22 @@ static int rtw_dbg_port(struct net_device *dev,
 	case 0x70:/* read_reg */
 		switch (minor_cmd) {
 		case 1:
-			DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+			tmp = rtw_read8(padapter, arg, &error);
+			if (error)
+				return error;
+			DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
 			break;
 		case 2:
-			DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+			tmp = rtw_read16(padapter, arg, &error);
+			if (error)
+				return error;
+			DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
 			break;
 		case 4:
-			DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+			tmp = rtw_read32(padapter, arg, &error);
+			if (error)
+				return error;
+			DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, tmp);
 			break;
 		}
 		break;
@@ -3992,15 +4022,15 @@ static int rtw_dbg_port(struct net_device *dev,
 		switch (minor_cmd) {
 		case 1:
 			rtw_write8(padapter, arg, extra_arg);
-			DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+			DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg, &error));
 			break;
 		case 2:
 			rtw_write16(padapter, arg, extra_arg);
-			DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+			DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg, &error));
 			break;
 		case 4:
 			rtw_write32(padapter, arg, extra_arg);
-			DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+			DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg, &error));
 			break;
 		}
 		break;
@@ -4096,7 +4126,10 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read8(padapter, reg);
+			final = rtw_read8(padapter, reg, &error);
+			if (error)
+				return error;
+
 			if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
 			else
@@ -4125,7 +4158,9 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read16(padapter, reg);
+			final = rtw_read16(padapter, reg, &error);
+			if (error)
+				return error;
 			if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
 			else
@@ -4153,7 +4188,9 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read32(padapter, reg);
+			final = rtw_read32(padapter, reg, &error);
+			if (error)
+				return error;
 			if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
 					reg, write_num, start_value, final);
@@ -4423,39 +4460,39 @@ static int rtw_dbg_port(struct net_device *dev,
 
 		case 0xfd:
 			rtw_write8(padapter, 0xc50, arg);
-			DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
+			DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50, &error));
 			rtw_write8(padapter, 0xc58, arg);
-			DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+			DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58, &error));
 			break;
 		case 0xfe:
-			DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
-			DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+			DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50, &error));
+			DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58, &error));
 			break;
 		case 0xff:
-			DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
-			DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
-			DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
-			DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
-			DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
+			DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210, &error));
+			DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608, &error));
+			DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280, &error));
+			DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284, &error));
+			DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288, &error));
 
-			DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
+			DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664, &error));
 
 			DBG_88E("\n");
 
-			DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
-			DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
+			DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430, &error));
+			DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438, &error));
 
-			DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
+			DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440, &error));
 
-			DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
+			DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458, &error));
 
-			DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
-			DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
+			DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484, &error));
+			DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488, &error));
 
-			DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
-			DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
-			DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
-			DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
+			DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444, &error));
+			DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448, &error));
+			DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c, &error));
+			DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450, &error));
 			break;
 		}
 		break;
@@ -5326,6 +5363,8 @@ static int rtw_mp_read_reg(struct net_device *dev,
 	char data[20], tmp[20];
 	u32 addr;
 	u32 ret, i = 0, j = 0, strtout = 0;
+	int error;
+	u32 tmp_;
 
 	if (!input)
 		return -ENOMEM;
@@ -5361,12 +5400,20 @@ static int rtw_mp_read_reg(struct net_device *dev,
 	switch (width) {
 	case 'b':
 		/*  1 byte */
-		sprintf(extra, "%d\n",  rtw_read8(padapter, addr));
+		tmp_ = rtw_read16(padapter, addr, &error);
+		if (error)
+			return error;
+
+		sprintf(extra, "%d\n", (u8) tmp_);
 		wrqu->length = strlen(extra);
 		break;
 	case 'w':
 		/*  2 bytes */
-		sprintf(data, "%04x\n", rtw_read16(padapter, addr));
+		tmp_ = rtw_read16(padapter, addr, &error);
+		if (error)
+			return error;
+
+		sprintf(data, "%04x\n", (u16) tmp_);
 		for (i = 0; i <= strlen(data); i++) {
 			if (i % 2 == 0) {
 				tmp[j] = ' ';
@@ -5396,8 +5443,12 @@ static int rtw_mp_read_reg(struct net_device *dev,
 		wrqu->length = 6;
 		break;
 	case 'd':
+		tmp_ = rtw_read32(padapter, addr, &error);
+		if (error)
+			return error;
+
 		/*  4 bytes */
-		sprintf(data, "%08x", rtw_read32(padapter, addr));
+		sprintf(data, "%08x", tmp_);
 		/* add read data format blank */
 		for (i = 0; i <= strlen(data); i++) {
 			if (i % 2 == 0) {
@@ -5889,6 +5940,8 @@ static int rtw_mp_arx(struct net_device *dev,
 	u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0;
 	char	*input = kmalloc(wrqu->length, GFP_KERNEL);
 	struct adapter *padapter = rtw_netdev_priv(dev);
+	u8 tmp;
+	int error;
 
 	if (!input)
 		return -ENOMEM;
@@ -5934,7 +5987,18 @@ static int rtw_mp_arx(struct net_device *dev,
 		OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF);
 		OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000);
 		OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF);
-		CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c));
+
+		tmp = rtw_read8(padapter, 0xa5b, &error);
+		if (error)
+			return error;
+
+		CCK_FA = (tmp << 8);
+
+		tmp = rtw_read8(padapter, 0xa5c, &error);
+		if (error)
+			return error;
+
+		CCK_FA |= (tmp);
 
 		sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA);
 	}
@@ -6097,20 +6161,30 @@ static int rtw_mp_dump(struct net_device *dev,
 	u8 rf_type, path_nums = 0;
 	u32 i, j = 1, path;
 	struct adapter *padapter = rtw_netdev_priv(dev);
+	int error;
+	u32 tmp;
 
 	if (strncmp(extra, "all", 4) == 0) {
 		DBG_88E("\n ======= MAC REG =======\n");
 		for (i = 0x0; i < 0x300; i += 4) {
 			if (j % 4 == 1)
 				DBG_88E("0x%02x", i);
-			DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+			
+			tmp = rtw_read32(padapter, i, &error);
+			if (!error)
+				DBG_88E(" 0x%08x ", tmp);
+
 			if ((j++) % 4 == 0)
 				DBG_88E("\n");
 		}
 		for (i = 0x400; i < 0x1000; i += 4) {
 			if (j % 4 == 1)
 				DBG_88E("0x%02x", i);
-			DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+
+			tmp = rtw_read32(padapter, i, &error);
+			if (!error)
+				DBG_88E(" 0x%08x ", tmp);
+
 			if ((j++) % 4 == 0)
 				DBG_88E("\n");
 		}
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC 2/3] staging: r8188eu: add error handling to ReadFuse
  2021-08-20 17:07 [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
  2021-08-20 17:07 ` [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling Pavel Skripkin
@ 2021-08-20 17:07 ` Pavel Skripkin
  2021-08-20 23:51   ` Phillip Potter
  2021-08-20 17:07 ` [PATCH RFC 3/3] staging: r8188eu: add error argument to read_macreg Pavel Skripkin
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-20 17:07 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

ReadEFuseByte() internally calls rtw_read8() which can fail. To avoid
uninit value bugs we should properly handle error sutiation and deliver
the error to caller.

To achieve it, some functions now return an int, and the error
which could occur in ReadEFuseByte() is handled on the top level.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_efuse.c      | 46 +++++++++-----
 drivers/staging/r8188eu/hal/hal_intf.c        |  6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 62 +++++++++++++------
 drivers/staging/r8188eu/hal/usb_halinit.c     | 20 ++++--
 drivers/staging/r8188eu/hal/usb_ops_linux.c   | 43 +++++++++++--
 drivers/staging/r8188eu/include/hal_intf.h    |  6 +-
 .../staging/r8188eu/include/rtl8188e_hal.h    |  2 +-
 drivers/staging/r8188eu/include/rtw_efuse.h   |  4 +-
 drivers/staging/r8188eu/os_dep/usb_intf.c     |  4 +-
 9 files changed, 138 insertions(+), 55 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index 47ff73b28380..5fcff0d6eb26 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -149,7 +149,7 @@ Efuse_CalculateWordCnts(u8 word_en)
 /*  */
 /* 	Created by Roger, 2008.10.21. */
 /*  */
-void
+int
 ReadEFuseByte(
 		struct adapter *Adapter,
 		u16 _offset,
@@ -163,32 +163,32 @@ ReadEFuseByte(
 
 	if (pseudo) {
 		Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
-		return;
+		return 0;
 	}
 
 	/* Write Address */
 	rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
 	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2, &error);
 	if (error)
-		return;
+		return error;
 	rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
 
 	/* Write bit 32 0 */
 	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3, &error);
 	if (error)
-		return;
+		return error;
 	rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
 
 	/* Check bit 32 read-ready */
 	retry = 0;
 	value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
 	if (error)
-		return;
+		return error;
 
 	while (!(((value32 >> 24) & 0xff) & 0x80)  && (retry < 10000)) {
 		value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
 		if (error)
-			return;
+			return error;
 		retry++;
 	}
 
@@ -199,9 +199,11 @@ ReadEFuseByte(
 	udelay(50);
 	value32 = rtw_read32(Adapter, EFUSE_CTRL, &error);
 	if (error)
-		return;
+		return error;
 
 	*pbuf = (u8)(value32 & 0xff);
+
+	return 0;
 }
 
 /*  */
@@ -222,9 +224,9 @@ ReadEFuseByte(
 /* 					write addr must be after sec5. */
 /*  */
 
-static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
+static int efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
 {
-	Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
+	return Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
 }
 
 void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
@@ -539,6 +541,7 @@ u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
 u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 {
 	u16 mapLen = 0;
+	int res;
 
 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
 
@@ -547,7 +550,9 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 
 	Efuse_PowerSwitch(padapter, false, true);
 
-	efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+	res = efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+	if (res)
+		return _FAIL;
 
 	Efuse_PowerSwitch(padapter, false, false);
 
@@ -557,6 +562,7 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 {
 	u16 mapLen = 0;
+	int res;
 
 	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
 
@@ -565,7 +571,9 @@ u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 
 	Efuse_PowerSwitch(padapter, false, true);
 
-	efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+	res = efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+	if (res)
+		return _FAIL;
 
 	Efuse_PowerSwitch(padapter, false, false);
 
@@ -836,17 +844,22 @@ efuse_ShadowRead4Byte(
  * 11/11/2008	MHC		Create Version 0.
  *
  *---------------------------------------------------------------------------*/
-static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
+static int Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
 {
 	u16 mapLen = 0;
+	int res;
 
 	Efuse_PowerSwitch(pAdapter, false, true);
 
 	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
 
-	efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+	res = efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+	if (res)
+		return res;
 
 	Efuse_PowerSwitch(pAdapter, false, false);
+
+	return res;
 }
 
 /*-----------------------------------------------------------------------------
@@ -865,20 +878,23 @@ static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse,
  * 11/13/2008	MHC		Create Version 0.
  *
  *---------------------------------------------------------------------------*/
-void EFUSE_ShadowMapUpdate(
+int EFUSE_ShadowMapUpdate(
 	struct adapter *pAdapter,
 	u8 efuseType,
 	bool pseudo)
 {
 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
 	u16 mapLen = 0;
+	int res = 0;
 
 	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
 
 	if (pEEPROM->bautoload_fail_flag)
 		memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
 	else
-		Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+		res = Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+
+	return res;
 } /*  EFUSE_ShadowMapUpdate */
 
 /*-----------------------------------------------------------------------------
diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c
index a6d589e89aeb..94536659cd7c 100644
--- a/drivers/staging/r8188eu/hal/hal_intf.c
+++ b/drivers/staging/r8188eu/hal/hal_intf.c
@@ -12,10 +12,12 @@ void rtw_hal_chip_configure(struct adapter *adapt)
 		adapt->HalFunc.intf_chip_configure(adapt);
 }
 
-void rtw_hal_read_chip_info(struct adapter *adapt)
+int rtw_hal_read_chip_info(struct adapter *adapt)
 {
 	if (adapt->HalFunc.read_adapter_info)
-		adapt->HalFunc.read_adapter_info(adapt);
+		return adapt->HalFunc.read_adapter_info(adapt);
+
+	return 0;
 }
 
 void rtw_hal_read_chip_version(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 0a2c08a24ad8..2ab58891ee9a 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -864,7 +864,7 @@ rtl8188e_EfusePowerSwitch(
 	hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
 }
 
-static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
+static int Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	u16			_offset,
 	u16			_size_byte,
 	u8 *pbuf,
@@ -879,6 +879,7 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	u16	**eFuseWord = NULL;
 	u16	efuse_utilized = 0;
 	u8 u1temp = 0;
+	int error;
 
 	/*  */
 	/*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
@@ -909,12 +910,16 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	/*  1. Read the first byte to check if efuse is empty!!! */
 	/*  */
 	/*  */
-	ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
-	if (*rtemp8 != 0xFF) {
+	error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+	if (error) {
+		DBG_88E("Failed to read EFUSE byte\n");
+		goto exit;
+	} else if (*rtemp8 != 0xFF) {
 		efuse_utilized++;
 		eFuse_Addr++;
 	} else {
 		DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
+		error = -ENOENT;
 		goto exit;
 	}
 
@@ -926,11 +931,15 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 		if ((*rtemp8 & 0x1F) == 0x0F) {		/* extended header */
 			u1temp = ((*rtemp8 & 0xE0) >> 5);
 
-			ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+			error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+			if (error)
+				goto exit;
 
 			if ((*rtemp8 & 0x0F) == 0x0F) {
 				eFuse_Addr++;
-				ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+				error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+				if (error)
+					goto exit;
 
 				if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
 					eFuse_Addr++;
@@ -951,13 +960,19 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
 				/*  Check word enable condition in the section */
 				if (!(wren & 0x01)) {
-					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					if (error)
+						goto exit;
+
 					eFuse_Addr++;
 					efuse_utilized++;
 					eFuseWord[offset][i] = (*rtemp8 & 0xff);
 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
 						break;
-					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					if (error)
+						goto exit;
+
 					eFuse_Addr++;
 					efuse_utilized++;
 					eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
@@ -969,7 +984,9 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 		}
 
 		/*  Read next PG header */
-		ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+		error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+		if (error)
+			goto exit;
 
 		if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
 			efuse_utilized++;
@@ -995,10 +1012,14 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 exit:
 	kfree(efuseTbl);
 	kfree(eFuseWord);
+
+	return error;
 }
 
-static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
 {
+	int res = 0;
+
 	if (!bPseudoTest) {
 		int ret = _FAIL;
 		if (rtw_IOL_applied(Adapter)) {
@@ -1012,25 +1033,25 @@ static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u1
 				goto exit;
 		}
 	}
-	Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+	res = Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
 
 exit:
-	return;
+	return res;
 }
 
-static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
 {
-	Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+	return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
 }
 
-static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
+static int rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
 			       u16 _offset, u16 _size_byte, u8 *pbuf,
 			       bool bPseudoTest)
 {
 	if (bPseudoTest)
-		ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+		return ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
 	else
-		ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+		return ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
 }
 
 /* Do not support BT */
@@ -2043,21 +2064,24 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
 	return status;
 }
 
-void
+int
 Hal_InitPGData88E(struct adapter *padapter)
 {
 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
+	int res = 0;
 
 	if (!pEEPROM->bautoload_fail_flag) { /*  autoload OK. */
 		if (!is_boot_from_eeprom(padapter)) {
 			/*  Read EFUSE real map to shadow. */
-			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+			res = EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
 		}
 	} else {/* autoload fail */
 		/* update to default value 0xFF */
 		if (!is_boot_from_eeprom(padapter))
-			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+			res = EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
 	}
+
+	return res;
 }
 
 void
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 73ef2e0ead19..8df8a8b7c738 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -1275,7 +1275,7 @@ readAdapterInfo_8188EU(
 	_ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
 }
 
-static void _ReadPROMContent(
+static int _ReadPROMContent(
 	struct adapter *Adapter
 	)
 {
@@ -1286,7 +1286,7 @@ static void _ReadPROMContent(
 	/* check system boot selection */
 	eeValue = rtw_read8(Adapter, REG_9346CR, &error);
 	if (error)
-		return;
+		return error;
 
 	eeprom->EepromOrEfuse		= (eeValue & BOOT_FROM_EEPROM) ? true : false;
 	eeprom->bautoload_fail_flag	= (eeValue & EEPROM_EN) ? false : true;
@@ -1294,8 +1294,13 @@ static void _ReadPROMContent(
 	DBG_88E("Boot from %s, Autoload %s !\n", (eeprom->EepromOrEfuse ? "EEPROM" : "EFUSE"),
 		(eeprom->bautoload_fail_flag ? "Fail" : "OK"));
 
-	Hal_InitPGData88E(Adapter);
+	error = Hal_InitPGData88E(Adapter);
+	if (error)
+		return error;
+
 	readAdapterInfo_8188EU(Adapter);
+
+	return 0;
 }
 
 static void _ReadRFType(struct adapter *Adapter)
@@ -1308,23 +1313,26 @@ static void _ReadRFType(struct adapter *Adapter)
 static int _ReadAdapterInfo8188EU(struct adapter *Adapter)
 {
 	u32 start = jiffies;
+	int res;
 
 	MSG_88E("====> %s\n", __func__);
 
 	_ReadRFType(Adapter);/* rf_chip -> _InitRFType() */
-	_ReadPROMContent(Adapter);
+	res = _ReadPROMContent(Adapter);
+	if (res)
+		return _FAIL;
 
 	MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
 
 	return _SUCCESS;
 }
 
-static void ReadAdapterInfo8188EU(struct adapter *Adapter)
+static int ReadAdapterInfo8188EU(struct adapter *Adapter)
 {
 	/*  Read EEPROM size before call any EEPROM function */
 	Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter);
 
-	_ReadAdapterInfo8188EU(Adapter);
+	return _ReadAdapterInfo8188EU(Adapter);
 }
 
 #define GPIO_DEBUG_PORT_NUM 0
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 980af6c02be5..f137b775976c 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -118,8 +118,14 @@ static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr, int *error)
 	len = 1;
 
 	res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
-	if (likely(error))
-		*error = res < 0? res: 0;
+	if (likely(error)) {
+		if (res < 0) {
+			pr_err("r8188eu: Failed to read 8 bytes: %d\n", res);
+			*error = res;
+		} else {
+			*error = 0;
+		}
+	}
 
 	return data;
 
@@ -130,12 +136,25 @@ static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr, int *error)
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
-	__le32 data;
+	__le32 data = 0;
+	int res;
+
+	if (unlikely(!error))
+		WARN_ON_ONCE("r8188eu: Reading w/o error checking is bad idea\n");
 
 	requesttype = 0x01;/* read_in */
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 2;
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	
+	res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	if (likely(error)) {
+		if (res < 0) {
+			pr_err("r8188eu: Failed to read 8 bytes: %d\n", res);
+			*error = res;
+		} else {
+			*error = 0;
+		}
+	}
 
 	return (u16)(le32_to_cpu(data) & 0xffff);
 }
@@ -145,14 +164,26 @@ static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr, int *error)
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
-	__le32 data;
+	__le32 data = 0;
+	int res;
+
+	if (unlikely(!error))
+		WARN_ON_ONCE("r8188eu: Reading w/o error checking is bad idea\n");
 
 	requesttype = 0x01;/* read_in */
 
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 4;
 
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	if (likely(error)) {
+		if (res < 0) {
+			pr_err("r8188eu: Failed to read 8 bytes: %d\n", res);
+			*error = res;
+		} else {
+			*error = 0;
+		}
+	}
 
 	return le32_to_cpu(data);
 }
diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h
index fa252540e596..9241af39e3a3 100644
--- a/drivers/staging/r8188eu/include/hal_intf.h
+++ b/drivers/staging/r8188eu/include/hal_intf.h
@@ -154,7 +154,7 @@ struct hal_ops {
 
 	void	(*intf_chip_configure)(struct adapter *padapter);
 
-	void	(*read_adapter_info)(struct adapter *padapter);
+	int	(*read_adapter_info)(struct adapter *padapter);
 
 	void	(*enable_interrupt)(struct adapter *padapter);
 	void	(*disable_interrupt)(struct adapter *padapter);
@@ -222,7 +222,7 @@ struct hal_ops {
 
 	void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite,
 				 u8 PwrState);
-	void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
+	int (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
 			  u16 _size_byte, u8 *pbuf, bool bPseudoTest);
 	void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType,
 					u8 type, void *pOut, bool bPseudoTest);
@@ -324,7 +324,7 @@ void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val);
 void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val);
 
 void rtw_hal_chip_configure(struct adapter *padapter);
-void rtw_hal_read_chip_info(struct adapter *padapter);
+int rtw_hal_read_chip_info(struct adapter *padapter);
 void rtw_hal_read_chip_version(struct adapter *padapter);
 
 u8 rtw_hal_set_def_var(struct adapter *padapter,
diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h
index 3939bf053de1..db9adbd0b024 100644
--- a/drivers/staging/r8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h
@@ -410,7 +410,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
 
 /*  EFuse */
 u8 GetEEPROMSize8188E(struct adapter *padapter);
-void Hal_InitPGData88E(struct adapter *padapter);
+int Hal_InitPGData88E(struct adapter *padapter);
 void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
 void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
 			    bool AutoLoadFail);
diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h
index b3ff46db2091..9657b66679e3 100644
--- a/drivers/staging/r8188eu/include/rtw_efuse.h
+++ b/drivers/staging/r8188eu/include/rtw_efuse.h
@@ -113,7 +113,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr,
 			  u16 cnts, u8 *data);
 u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test);
 u8 Efuse_CalculateWordCnts(u8 word_en);
-void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
+int ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
 void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1,
 			      void *out, bool bPseudoTest);
 u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test);
@@ -128,7 +128,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr,
 			     u8 word_en, u8 *data, bool test);
 
 u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address);
-void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
+int EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
 void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val);
 
 #endif
diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c
index e002070f7fba..f950a31d061e 100644
--- a/drivers/staging/r8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/r8188eu/os_dep/usb_intf.c
@@ -608,7 +608,9 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
 	rtw_hal_chip_configure(padapter);
 
 	/* step read efuse/eeprom data and get mac_addr */
-	rtw_hal_read_chip_info(padapter);
+	status = rtw_hal_read_chip_info(padapter);
+	if (status)
+		goto free_hal_data;
 
 	/* step 5. */
 	if (rtw_init_drv_sw(padapter) == _FAIL)
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC 3/3] staging: r8188eu: add error argument to read_macreg
  2021-08-20 17:07 [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
  2021-08-20 17:07 ` [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling Pavel Skripkin
  2021-08-20 17:07 ` [PATCH RFC 2/3] staging: r8188eu: add error handling to ReadFuse Pavel Skripkin
@ 2021-08-20 17:07 ` Pavel Skripkin
  2021-08-20 23:18   ` Phillip Potter
  2021-08-20 23:12 ` [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs Phillip Potter
  2021-08-22  9:53 ` Fabio M. De Francesco
  4 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-20 17:07 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

Since read_macreg() calls rtw_read*() internally we should tell
callers about an error on the read side.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_mp.c    | 9 ++++-----
 drivers/staging/r8188eu/include/rtw_mp.h | 2 +-
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 601a1fd5d4e7..6bbea1cc364a 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -7,20 +7,19 @@
 #include "../include/odm_precomp.h"
 #include "../include/rtl8188e_hal.h"
 
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
+u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz, int *error)
 {
 	u32 val = 0;
-	int error;
 
 	switch (sz) {
 	case 1:
-		val = rtw_read8(padapter, addr, &error);
+		val = rtw_read8(padapter, addr, error);
 		break;
 	case 2:
-		val = rtw_read16(padapter, addr, &error);
+		val = rtw_read16(padapter, addr, error);
 		break;
 	case 4:
-		val = rtw_read32(padapter, addr, &error);
+		val = rtw_read32(padapter, addr, error);
 		break;
 	default:
 		val = 0xffffffff;
diff --git a/drivers/staging/r8188eu/include/rtw_mp.h b/drivers/staging/r8188eu/include/rtw_mp.h
index b64b16554343..c063e6216249 100644
--- a/drivers/staging/r8188eu/include/rtw_mp.h
+++ b/drivers/staging/r8188eu/include/rtw_mp.h
@@ -410,7 +410,7 @@ void mp_stop_test(struct adapter *padapter);
 u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask);
 void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val);
 
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz);
+u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz, int *error);
 void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz);
 u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask);
 void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val);
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling
  2021-08-20 17:07 ` [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling Pavel Skripkin
@ 2021-08-20 21:50   ` Pavel Skripkin
  2021-08-20 23:41   ` Phillip Potter
  2021-08-21  5:55   ` Fabio M. De Francesco
  2 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-20 21:50 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel

On 8/20/21 8:07 PM, Pavel Skripkin wrote:
[snip]

> @@ -336,13 +338,21 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
>   
>   	memset(c2h_evt, 0, 16);
>   
> -	*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
> -	*(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
> +	*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, &error);
> +	if (error)
> +		goto clear_evt;
> +
> +	*(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, &error);
> +	if (error)
> +		;
	 ^^^^^^^

Should be goto clear_evt;. Will fix in v2, I want to receive some 
feedback first :)



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-20 17:07 [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
                   ` (2 preceding siblings ...)
  2021-08-20 17:07 ` [PATCH RFC 3/3] staging: r8188eu: add error argument to read_macreg Pavel Skripkin
@ 2021-08-20 23:12 ` Phillip Potter
  2021-08-21 10:42   ` Pavel Skripkin
  2021-08-22  9:53 ` Fabio M. De Francesco
  4 siblings, 1 reply; 118+ messages in thread
From: Phillip Potter @ 2021-08-20 23:12 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: linux-staging, linux-kernel, Larry.Finger, gregkh, straube.linux,
	fmdefrancesco

On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
> 
> I noticed, that new staging driver was added like 3 weeks ago and I
> decided
> to look at the code, because drivers in staging directory are always
> buggy.
> 
> The first thing I noticed is *no one* was checking read operations
> result, but
> it can fail and driver may start writing random stack values into
> registers. It
> can cause driver misbehavior or device misbehavior.
> 
> To avoid this type of bugs, i've expanded read() API with error
> parametr,
> which will be initialized to error if read fails. It helps callers to
> break/return earlier and don't write random values to registers or to
> rely
> on random values.
> 
> Why is this pacth series RFC?
>   1. I don't have this device and I cannot test these changes.
>   2. I don't know how to handle errors in each particular case. For
> now, function
>      just returns or returns an error. That's all. I hope, driver
> maintainers will
>      help with these bits.
>   3. I guess, I handled not all uninit value bugs here. I hope, I
> fixed
>      at least half of them
> 
> This series was build-tested and made on top of staging-testing
> branch
> 
> 
> With regards,
> Pavel Skripkin
> 
> Pavel Skripkin (3):
>   staging: r8188eu: add proper rtw_read* error handling
>   staging: r8188eu: add error handling to ReadFuse
>   staging: r8188eu: add error argument to read_macreg
> 
>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>  drivers/staging/r8188eu/core/rtw_efuse.c      | 119 +++--
>  drivers/staging/r8188eu/core/rtw_io.c         |  18 +-
>  drivers/staging/r8188eu/core/rtw_mp.c         |  38 +-
>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  20 +-
>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   6 +-
>  drivers/staging/r8188eu/core/rtw_sreset.c     |   7 +-
>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>  drivers/staging/r8188eu/hal/hal_com.c         |  22 +-
>  drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  37 +-
>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 260 ++++++++---
>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  26 +-
>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  20 +-
>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  17 +-
>  drivers/staging/r8188eu/hal/usb_halinit.c     | 412 ++++++++++++++--
> --
>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  55 ++-
>  drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
>  .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
>  drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>  drivers/staging/r8188eu/include/rtw_mp.h      |   2 +-
>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 168 +++++--
>  drivers/staging/r8188eu/os_dep/usb_intf.c     |   4 +-
>  26 files changed, 1072 insertions(+), 301 deletions(-)
> 

Dear Pavel,

Firstly, thank you for this contribution, it is much appreciated.
Whilst I'm still learning myself when it comes to this driver and to
kernel code in general, I can certainly say the code looks pretty good
in general so far. I will try and offer individual comments on each
patch.

Regards,
Phil


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 3/3] staging: r8188eu: add error argument to read_macreg
  2021-08-20 17:07 ` [PATCH RFC 3/3] staging: r8188eu: add error argument to read_macreg Pavel Skripkin
@ 2021-08-20 23:18   ` Phillip Potter
  2021-08-21 10:38     ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: Phillip Potter @ 2021-08-20 23:18 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: linux-staging, linux-kernel, Larry.Finger, gregkh, straube.linux,
	fmdefrancesco

On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
> Since read_macreg() calls rtw_read*() internally we should tell
> callers about an error on the read side.
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
>  drivers/staging/r8188eu/core/rtw_mp.c    | 9 ++++-----
>  drivers/staging/r8188eu/include/rtw_mp.h | 2 +-
>  2 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/r8188eu/core/rtw_mp.c
> b/drivers/staging/r8188eu/core/rtw_mp.c
> index 601a1fd5d4e7..6bbea1cc364a 100644
> --- a/drivers/staging/r8188eu/core/rtw_mp.c
> +++ b/drivers/staging/r8188eu/core/rtw_mp.c
> @@ -7,20 +7,19 @@
>  #include "../include/odm_precomp.h"
>  #include "../include/rtl8188e_hal.h"
>  
> -u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
> +u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz, int
> *error)

Dear Pavel,

Correct me if I'm wrong, but this read_macreg function seems to be
completely unused by the rest of the driver. Rather than changing the
signature to do error handling, maybe it would be better to just remove
it?

That is just my view though, would be interested to see what others
think - perhaps it could come in handy at some point.

Regards,
Phil


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling
  2021-08-20 17:07 ` [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling Pavel Skripkin
  2021-08-20 21:50   ` Pavel Skripkin
@ 2021-08-20 23:41   ` Phillip Potter
  2021-08-21  5:55   ` Fabio M. De Francesco
  2 siblings, 0 replies; 118+ messages in thread
From: Phillip Potter @ 2021-08-20 23:41 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: linux-staging, linux-kernel, Larry.Finger, gregkh, straube.linux,
	fmdefrancesco

On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
> rtw_read*() functions call usb_read* inside. These functions could
> fail
> in some cases; for example: failed to receive control message. These
> cases should be handled to prevent uninit value bugs, since usb_read*
> functions blindly return stack variable without checking if this
> value
> _actualy_ initialized.
> 
> To achive it, all usb_read* and rtw_read*() argument list is expanded
> with pointer to error and added error usbctrl_vendorreq() error
> checking.
> If transfer is successful error will be initialized to 0 otherwise to
> error returned from usb_control_msg().
> 
> To not break the build, added error checking for rtw_read*() call all
> across the driver.
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>  drivers/staging/r8188eu/core/rtw_efuse.c      |  83 +++-
>  drivers/staging/r8188eu/core/rtw_io.c         |  18 +-
>  drivers/staging/r8188eu/core/rtw_mp.c         |  37 +-
>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  20 +-
>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   6 +-
>  drivers/staging/r8188eu/core/rtw_sreset.c     |   7 +-
>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>  drivers/staging/r8188eu/hal/hal_com.c         |  22 +-
>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  37 +-
>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 198 +++++++--
>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  26 +-
>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  20 +-
>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  17 +-
>  drivers/staging/r8188eu/hal/usb_halinit.c     | 394 ++++++++++++++--
> --
>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  16 +-
>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 168 +++++---
>  20 files changed, 941 insertions(+), 252 deletions(-)
> 
...
> diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c
> b/drivers/staging/r8188eu/hal/usb_ops_linux.c
> index 953fa05dc30c..980af6c02be5 100644
> --- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
> +++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
> @@ -101,29 +101,31 @@ static int usbctrl_vendorreq(struct intf_hdl
> *pintfhdl, u16 value, void *pdata,
>         return status;
>  }
>  
> -static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
> +static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr, int *error)
>  {
>         u8 requesttype;
>         u16 wvalue;
>         u16 len;
>         u8 data = 0;
> +       int res;
>  
> -
> +       if (unlikely(!error))
> +               WARN_ON_ONCE("r8188eu: Reading w/o error checking is
> bad idea\n");
>  
>         requesttype = 0x01;/* read_in */
>  
>         wvalue = (u16)(addr & 0x0000ffff);
>         len = 1;
>  
> -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> -
> -
> +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len,
> requesttype);
> +       if (likely(error))
> +               *error = res < 0? res: 0;
>  
>         return data;
>  
>  }
>  
> -static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> +static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr, int
> *error)
>  {
>         u8 requesttype;
>         u16 wvalue;
> @@ -138,7 +140,7 @@ static u16 usb_read16(struct intf_hdl *pintfhdl,
> u32 addr)
>         return (u16)(le32_to_cpu(data) & 0xffff);
>  }
>  
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr, int
> *error)
>  {
>         u8 requesttype;
>         u16 wvalue;

Dear Pavel,

For this patch, you modify the signature of the usb_read*() functions,
but only introduce the usbctrl_vendorreq checks for usb_read8.

I can see from the following patch that you have done the others too
later on, but really I would say for changes like this, they should be
grouped in the same patch. Also, just me nitpicking probably, but the
patch is rather large - sometimes unavoidable I know, but perhaps
better to group logically into areas (files or types of change) in
order to get the patches smaller and thus more easily reviewable. Many
thanks.

In terms of what we do with the errors, I would invite comments from
others on this too due to my inexperience, but I like your thinking.

Regards,
Phil


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 2/3] staging: r8188eu: add error handling to ReadFuse
  2021-08-20 17:07 ` [PATCH RFC 2/3] staging: r8188eu: add error handling to ReadFuse Pavel Skripkin
@ 2021-08-20 23:51   ` Phillip Potter
  2021-08-21  3:59     ` Fabio M. De Francesco
  0 siblings, 1 reply; 118+ messages in thread
From: Phillip Potter @ 2021-08-20 23:51 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry Finger, Greg KH, Michael Straube, Fabio M. De Francesco,
	linux-staging, Linux Kernel Mailing List

On Fri, 20 Aug 2021 at 18:07, Pavel Skripkin <paskripkin@gmail.com> wrote:
>
> ReadEFuseByte() internally calls rtw_read8() which can fail. To avoid
> uninit value bugs we should properly handle error sutiation and deliver
> the error to caller.
>
> To achieve it, some functions now return an int, and the error
> which could occur in ReadEFuseByte() is handled on the top level.
>
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
>  drivers/staging/r8188eu/core/rtw_efuse.c      | 46 +++++++++-----
>  drivers/staging/r8188eu/hal/hal_intf.c        |  6 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 62 +++++++++++++------
>  drivers/staging/r8188eu/hal/usb_halinit.c     | 20 ++++--
>  drivers/staging/r8188eu/hal/usb_ops_linux.c   | 43 +++++++++++--
>  drivers/staging/r8188eu/include/hal_intf.h    |  6 +-
>  .../staging/r8188eu/include/rtl8188e_hal.h    |  2 +-
>  drivers/staging/r8188eu/include/rtw_efuse.h   |  4 +-
>  drivers/staging/r8188eu/os_dep/usb_intf.c     |  4 +-
>  9 files changed, 138 insertions(+), 55 deletions(-)
>

Dear Pavel,

I like the code, just a few things though:
(1) the comments I made in the previous e-mail r.e. what we actually
do with the errors, and grouping logically related changes (the rest
of the usb_read*() changes being in this patch for example).
(2) I got trailing whitespace errors from this patch and the last one.
For a v2 I would say stripping the whitespace is a good idea too - I
have submitted many patches myself to this driver that had whitespace
in - indeed, the original version of my patch series to import the
driver still had a load as well :-)

Regards,
Phil

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 2/3] staging: r8188eu: add error handling to ReadFuse
  2021-08-20 23:51   ` Phillip Potter
@ 2021-08-21  3:59     ` Fabio M. De Francesco
  0 siblings, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-21  3:59 UTC (permalink / raw)
  To: Pavel Skripkin, Phillip Potter
  Cc: Larry Finger, Greg KH, Michael Straube, linux-staging,
	Linux Kernel Mailing List

Dear Pavel

On Saturday, August 21, 2021 1:51:57 AM CEST Phillip Potter wrote:
> On Fri, 20 Aug 2021 at 18:07, Pavel Skripkin <paskripkin@gmail.com> wrote:
> >
> > ReadEFuseByte() internally calls rtw_read8() which can fail. To avoid
> > uninit value bugs we should properly handle error sutiation and deliver

sutiation --> situation.

> > the error to caller.
> >
> > To achieve it, some functions now return an int, and the error
> > which could occur in ReadEFuseByte() is handled on the top level.
> >
> > Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> > ---
> >  drivers/staging/r8188eu/core/rtw_efuse.c      | 46 +++++++++-----
> >  drivers/staging/r8188eu/hal/hal_intf.c        |  6 +-
> >  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 62 +++++++++++++------
> >  drivers/staging/r8188eu/hal/usb_halinit.c     | 20 ++++--
> >  drivers/staging/r8188eu/hal/usb_ops_linux.c   | 43 +++++++++++--
> >  drivers/staging/r8188eu/include/hal_intf.h    |  6 +-
> >  .../staging/r8188eu/include/rtl8188e_hal.h    |  2 +-
> >  drivers/staging/r8188eu/include/rtw_efuse.h   |  4 +-
> >  drivers/staging/r8188eu/os_dep/usb_intf.c     |  4 +-
> >  9 files changed, 138 insertions(+), 55 deletions(-)
> >

Please change the Subject: ReadFuse --> ReadEFuse() or 
ReadFuse --> ReadEFuseByte().

> 
> Dear Pavel,
> 
> I like the code, just a few things though:
> (1) the comments I made in the previous e-mail r.e. what we actually
> do with the errors, and grouping logically related changes (the rest
> of the usb_read*() changes being in this patch for example).

I agree with Philip on splitting 1/3 into more patches, perhaps one for each
of the three rtw_read*(), but I disagree on merging the usb_read*() changes 
into this. They should go to another patch because they are not strictly
related to "add[ing] error handling to ReadFuse".

Regards,

Fabio

> (2) I got trailing whitespace errors from this patch and the last one.
> For a v2 I would say stripping the whitespace is a good idea too - I
> have submitted many patches myself to this driver that had whitespace
> in - indeed, the original version of my patch series to import the
> driver still had a load as well :-)
> 
> Regards,
> Phil
> 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling
  2021-08-20 17:07 ` [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling Pavel Skripkin
  2021-08-20 21:50   ` Pavel Skripkin
  2021-08-20 23:41   ` Phillip Potter
@ 2021-08-21  5:55   ` Fabio M. De Francesco
  2021-08-21 10:35     ` Pavel Skripkin
  2 siblings, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-21  5:55 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel, Pavel Skripkin

On Friday, August 20, 2021 7:07:36 PM CEST Pavel Skripkin wrote:
> rtw_read*() functions call usb_read* inside. These functions could fail
> in some cases; for example: failed to receive control message. These
> cases should be handled to prevent uninit value bugs, since usb_read*
> functions blindly return stack variable without checking if this value
> _actualy_ initialized.
> 
> To achive it, all usb_read* and rtw_read*() argument list is expanded

Dear Pavel,

Please, achive --> achieve.

> with pointer to error and added error usbctrl_vendorreq() error checking.
> If transfer is successful error will be initialized to 0 otherwise to
> error returned from usb_control_msg().
> 
> To not break the build, added error checking for rtw_read*() call all
> across the driver.
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>  drivers/staging/r8188eu/core/rtw_efuse.c      |  83 +++-
>  drivers/staging/r8188eu/core/rtw_io.c         |  18 +-
>  drivers/staging/r8188eu/core/rtw_mp.c         |  37 +-
>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  20 +-
>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   6 +-
>  drivers/staging/r8188eu/core/rtw_sreset.c     |   7 +-
>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>  drivers/staging/r8188eu/hal/hal_com.c         |  22 +-
>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  37 +-
>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 198 +++++++--
>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  26 +-
>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  20 +-
>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  17 +-
>  drivers/staging/r8188eu/hal/usb_halinit.c     | 394 ++++++++++++++----
>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  16 +-
>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 168 +++++---
>  20 files changed, 941 insertions(+), 252 deletions(-)

I agree with Philip: please, split this long patch. If I were you, I'd make 
one patch for each of the three rtw_read*() and a fourth patch for usb_read*().

> --- a/drivers/staging/r8188eu/core/rtw_io.c
> +++ b/drivers/staging/r8188eu/core/rtw_io.c
> @@ -34,44 +34,44 @@ jackson@realtek.com.tw
>  #define rtw_cpu_to_le16(val)		cpu_to_le16(val)
>  #define rtw_cpu_to_le32(val)		cpu_to_le32(val)

Not related to your patch, these macros are useless and misleading.

> -u8 _rtw_read8(struct adapter *adapter, u32 addr)
> +u8 _rtw_read8(struct adapter *adapter, u32 addr, int *error)
>  {
>  	u8 r_val;
>  	struct io_priv *pio_priv = &adapter->iopriv;
>  	struct	intf_hdl *pintfhdl = &pio_priv->intf;
> -	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
> +	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>  
>  
>  	_read8 = pintfhdl->io_ops._read8;
> -	r_val = _read8(pintfhdl, addr);
> +	r_val = _read8(pintfhdl, addr, error);
>  
>  	return r_val;
>  }

I really don't like passing errors through arguments. Why don't you pass 
a storage location where the function save the byte read and instead use the 
return for errors? I think that this would result in a cleaner design. Furthermore,
it is used everywhere in the kernel.
  
> -u16 _rtw_read16(struct adapter *adapter, u32 addr)
> +u16 _rtw_read16(struct adapter *adapter, u32 addr, int *error)
>  {
>  	u16 r_val;
>  	struct io_priv *pio_priv = &adapter->iopriv;
>  	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
> -	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
> +	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>  
>  	_read16 = pintfhdl->io_ops._read16;
>  
> -	r_val = _read16(pintfhdl, addr);
> +	r_val = _read16(pintfhdl, addr, error);
>  
>  	return r_val;
>  }

Same.

> -u32 _rtw_read32(struct adapter *adapter, u32 addr)
> +u32 _rtw_read32(struct adapter *adapter, u32 addr, int *error)
>  {
>  	u32 r_val;
>  	struct io_priv *pio_priv = &adapter->iopriv;
>  	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
> -	u32	(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
> +	u32	(*_read32)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>  
>  	_read32 = pintfhdl->io_ops._read32;
>  
> -	r_val = _read32(pintfhdl, addr);
> +	r_val = _read32(pintfhdl, addr, error);
>  
>  	return r_val;
>  }

Same.

I'm done for now: too many lines to read all at once :)

Regards,

Fabio



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling
  2021-08-21  5:55   ` Fabio M. De Francesco
@ 2021-08-21 10:35     ` Pavel Skripkin
  2021-08-21 12:11       ` Fabio M. De Francesco
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-21 10:35 UTC (permalink / raw)
  To: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux
  Cc: linux-staging, linux-kernel

On 8/21/21 8:55 AM, Fabio M. De Francesco wrote:
> On Friday, August 20, 2021 7:07:36 PM CEST Pavel Skripkin wrote:
>> rtw_read*() functions call usb_read* inside. These functions could fail
>> in some cases; for example: failed to receive control message. These
>> cases should be handled to prevent uninit value bugs, since usb_read*
>> functions blindly return stack variable without checking if this value
>> _actualy_ initialized.
>> 
>> To achive it, all usb_read* and rtw_read*() argument list is expanded
> 
> Dear Pavel,
> 
> Please, achive --> achieve.
> 
>> with pointer to error and added error usbctrl_vendorreq() error checking.
>> If transfer is successful error will be initialized to 0 otherwise to
>> error returned from usb_control_msg().
>> 
>> To not break the build, added error checking for rtw_read*() call all
>> across the driver.
>> 
>> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
>> ---
>>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>>  drivers/staging/r8188eu/core/rtw_efuse.c      |  83 +++-
>>  drivers/staging/r8188eu/core/rtw_io.c         |  18 +-
>>  drivers/staging/r8188eu/core/rtw_mp.c         |  37 +-
>>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  20 +-
>>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   6 +-
>>  drivers/staging/r8188eu/core/rtw_sreset.c     |   7 +-
>>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>>  drivers/staging/r8188eu/hal/hal_com.c         |  22 +-
>>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  37 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 198 +++++++--
>>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  26 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  20 +-
>>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  17 +-
>>  drivers/staging/r8188eu/hal/usb_halinit.c     | 394 ++++++++++++++----
>>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  16 +-
>>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 168 +++++---
>>  20 files changed, 941 insertions(+), 252 deletions(-)
> 

Hi, Fabio!


Thank you for feedback

> I agree with Philip: please, split this long patch. If I were you, I'd make
> one patch for each of the three rtw_read*() and a fourth patch for usb_read*().
> 

Make sense. Will fix in v2.

>> --- a/drivers/staging/r8188eu/core/rtw_io.c
>> +++ b/drivers/staging/r8188eu/core/rtw_io.c
>> @@ -34,44 +34,44 @@ jackson@realtek.com.tw
>>  #define rtw_cpu_to_le16(val)		cpu_to_le16(val)
>>  #define rtw_cpu_to_le32(val)		cpu_to_le32(val)
> 
> Not related to your patch, these macros are useless and misleading.
> 

Sorry, I don't get it. I didn't touch these macros, it's part of diffstat.

>> -u8 _rtw_read8(struct adapter *adapter, u32 addr)
>> +u8 _rtw_read8(struct adapter *adapter, u32 addr, int *error)
>>  {
>>  	u8 r_val;
>>  	struct io_priv *pio_priv = &adapter->iopriv;
>>  	struct	intf_hdl *pintfhdl = &pio_priv->intf;
>> -	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
>> +	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>>  
>>  
>>  	_read8 = pintfhdl->io_ops._read8;
>> -	r_val = _read8(pintfhdl, addr);
>> +	r_val = _read8(pintfhdl, addr, error);
>>  
>>  	return r_val;
>>  }
> 
> I really don't like passing errors through arguments. Why don't you pass
> a storage location where the function save the byte read and instead use the
> return for errors? I think that this would result in a cleaner design. Furthermore,
> it is used everywhere in the kernel.
>    

Yep, this will be more cleaner, but I decided to receive some feedback 
first about the idea. If this error handling is really necessary, I will 
rework this approach :)


>> -u16 _rtw_read16(struct adapter *adapter, u32 addr)
>> +u16 _rtw_read16(struct adapter *adapter, u32 addr, int *error)
>>  {
>>  	u16 r_val;
>>  	struct io_priv *pio_priv = &adapter->iopriv;
>>  	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
>> -	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
>> +	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>>  
>>  	_read16 = pintfhdl->io_ops._read16;
>>  
>> -	r_val = _read16(pintfhdl, addr);
>> +	r_val = _read16(pintfhdl, addr, error);
>>  
>>  	return r_val;
>>  }
> 
> Same.
> 
>> -u32 _rtw_read32(struct adapter *adapter, u32 addr)
>> +u32 _rtw_read32(struct adapter *adapter, u32 addr, int *error)
>>  {
>>  	u32 r_val;
>>  	struct io_priv *pio_priv = &adapter->iopriv;
>>  	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
>> -	u32	(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
>> +	u32	(*_read32)(struct intf_hdl *pintfhdl, u32 addr, int *error);
>>  
>>  	_read32 = pintfhdl->io_ops._read32;
>>  
>> -	r_val = _read32(pintfhdl, addr);
>> +	r_val = _read32(pintfhdl, addr, error);
>>  
>>  	return r_val;
>>  }
> 
> Same.
> 
> I'm done for now: too many lines to read all at once :)
> 



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 3/3] staging: r8188eu: add error argument to read_macreg
  2021-08-20 23:18   ` Phillip Potter
@ 2021-08-21 10:38     ` Pavel Skripkin
  0 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-21 10:38 UTC (permalink / raw)
  To: Phillip Potter
  Cc: linux-staging, linux-kernel, Larry.Finger, gregkh, straube.linux,
	fmdefrancesco

On 8/21/21 2:18 AM, Phillip Potter wrote:
> On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
>> Since read_macreg() calls rtw_read*() internally we should tell
>> callers about an error on the read side.
>> 
>> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
>> ---
>>  drivers/staging/r8188eu/core/rtw_mp.c    | 9 ++++-----
>>  drivers/staging/r8188eu/include/rtw_mp.h | 2 +-
>>  2 files changed, 5 insertions(+), 6 deletions(-)
>> 
>> diff --git a/drivers/staging/r8188eu/core/rtw_mp.c
>> b/drivers/staging/r8188eu/core/rtw_mp.c
>> index 601a1fd5d4e7..6bbea1cc364a 100644
>> --- a/drivers/staging/r8188eu/core/rtw_mp.c
>> +++ b/drivers/staging/r8188eu/core/rtw_mp.c
>> @@ -7,20 +7,19 @@
>>  #include "../include/odm_precomp.h"
>>  #include "../include/rtl8188e_hal.h"
>>  
>> -u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
>> +u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz, int
>> *error)
> 
> Dear Pavel,
> 
> Correct me if I'm wrong, but this read_macreg function seems to be
> completely unused by the rest of the driver. Rather than changing the
> signature to do error handling, maybe it would be better to just remove
> it?
> 
> That is just my view though, would be interested to see what others
> think - perhaps it could come in handy at some point.
> 

yes, this function is unused for now, but I am aware about plans for 
this function :) If no one has plans for it, it can be removed.


With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-20 23:12 ` [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs Phillip Potter
@ 2021-08-21 10:42   ` Pavel Skripkin
  0 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-21 10:42 UTC (permalink / raw)
  To: Phillip Potter
  Cc: linux-staging, linux-kernel, Larry.Finger, gregkh, straube.linux,
	fmdefrancesco

On 8/21/21 2:12 AM, Phillip Potter wrote:
> On Fri, 2021-08-20 at 20:07 +0300, Pavel Skripkin wrote:
>> Hi, Greg, Larry and Phillip!
>> 
>> I noticed, that new staging driver was added like 3 weeks ago and I
>> decided
>> to look at the code, because drivers in staging directory are always
>> buggy.
>> 
>> The first thing I noticed is *no one* was checking read operations
>> result, but
>> it can fail and driver may start writing random stack values into
>> registers. It
>> can cause driver misbehavior or device misbehavior.
>> 
>> To avoid this type of bugs, i've expanded read() API with error
>> parametr,
>> which will be initialized to error if read fails. It helps callers to
>> break/return earlier and don't write random values to registers or to
>> rely
>> on random values.
>> 
>> Why is this pacth series RFC?
>>   1. I don't have this device and I cannot test these changes.
>>   2. I don't know how to handle errors in each particular case. For
>> now, function
>>      just returns or returns an error. That's all. I hope, driver
>> maintainers will
>>      help with these bits.
>>   3. I guess, I handled not all uninit value bugs here. I hope, I
>> fixed
>>      at least half of them
>> 
>> This series was build-tested and made on top of staging-testing
>> branch
>> 
>> 
>> With regards,
>> Pavel Skripkin
>> 
>> Pavel Skripkin (3):
>>   staging: r8188eu: add proper rtw_read* error handling
>>   staging: r8188eu: add error handling to ReadFuse
>>   staging: r8188eu: add error argument to read_macreg
>> 
>>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>>  drivers/staging/r8188eu/core/rtw_efuse.c      | 119 +++--
>>  drivers/staging/r8188eu/core/rtw_io.c         |  18 +-
>>  drivers/staging/r8188eu/core/rtw_mp.c         |  38 +-
>>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  20 +-
>>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   6 +-
>>  drivers/staging/r8188eu/core/rtw_sreset.c     |   7 +-
>>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>>  drivers/staging/r8188eu/hal/hal_com.c         |  22 +-
>>  drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
>>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  37 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 260 ++++++++---
>>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  26 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  20 +-
>>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  17 +-
>>  drivers/staging/r8188eu/hal/usb_halinit.c     | 412 ++++++++++++++--
>> --
>>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  55 ++-
>>  drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
>>  .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
>>  drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
>>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>>  drivers/staging/r8188eu/include/rtw_mp.h      |   2 +-
>>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 168 +++++--
>>  drivers/staging/r8188eu/os_dep/usb_intf.c     |   4 +-
>>  26 files changed, 1072 insertions(+), 301 deletions(-)
>> 
> 
> Dear Pavel,
> 
> Firstly, thank you for this contribution, it is much appreciated.
> Whilst I'm still learning myself when it comes to this driver and to
> kernel code in general, I can certainly say the code looks pretty good
> in general so far. I will try and offer individual comments on each
> patch.
> 

Thank you for your feedback. So, I will prepare a v2 version in few days 
and, I think, I will leave RFC prefix.

Also, I want to receive some feedback from Larry about error handling in 
each particular case, I guess, he can help us with it.

So, I will split each rtw_read* changes into separate patche and make 
them return an error instead of read value.


Again, big thanks to you and Fabio for feedback, I appreciate it :)




With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 1/3] staging: r8188eu: add proper rtw_read* error handling
  2021-08-21 10:35     ` Pavel Skripkin
@ 2021-08-21 12:11       ` Fabio M. De Francesco
  0 siblings, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-21 12:11 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel

On Saturday, August 21, 2021 12:35:48 PM CEST Pavel Skripkin wrote:
> On 8/21/21 8:55 AM, Fabio M. De Francesco wrote:
> > On Friday, August 20, 2021 7:07:36 PM CEST Pavel Skripkin wrote:
> >> rtw_read*() functions call usb_read* inside. These functions could fail
> >> in some cases; for example: failed to receive control message. These
> >> cases should be handled to prevent uninit value bugs, since usb_read*
> >> functions blindly return stack variable without checking if this value
> >> _actualy_ initialized.
> >> 
> >> To achive it, all usb_read* and rtw_read*() argument list is expanded
> > 
> > []
> >
> >> --- a/drivers/staging/r8188eu/core/rtw_io.c
> >> +++ b/drivers/staging/r8188eu/core/rtw_io.c
> >> @@ -34,44 +34,44 @@ jackson@realtek.com.tw
> >>  #define rtw_cpu_to_le16(val)		cpu_to_le16(val)
> >>  #define rtw_cpu_to_le32(val)		cpu_to_le32(val)
> > 
> > Not related to your patch, these macros are useless and misleading.
> > 
> 
> Sorry, I don't get it. I didn't touch these macros, it's part of diffstat.

Yes, correct; in fact I wrote: "not related to your patch".

I just saw those macros while reading your patch. The code is  I just noticed 
that those macros are useless (in case someone wanted to
address that issue). 

Obviously, if you find it interesting, you shouldn't do that in your series,
because it is entirely unrelated to the purpose of your work.

I hope now I've made it clearer, sorry.

Regards,

Fabio 



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-20 17:07 [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
                   ` (3 preceding siblings ...)
  2021-08-20 23:12 ` [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs Phillip Potter
@ 2021-08-22  9:53 ` Fabio M. De Francesco
  2021-08-22 10:09   ` Pavel Skripkin
  4 siblings, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-22  9:53 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel, Pavel Skripkin, Michael Straube,
	Martin Kaiser

On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
> 
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
> 
> The first thing I noticed is *no one* was checking read operations result, 
but
> it can fail and driver may start writing random stack values into registers. 
It
> can cause driver misbehavior or device misbehavior.

After the messages I wrote yesterday, I had some minutes to look deeper at the 
code that would be changed by these patches.

I think that it does not look like that the driver could return "random stack 
values into registers" and I think this entire series in unnecessary. 

As far as I understand this driver (though I must admit that I really don't 
know how to write drivers, and I'm not interested in understanding - at the 
moment, at least), all the usb_read*() call usbctrl_vendorreq() and the latter 
*does* proper error checking before returning to the callers the read data. 

Please, look at the code copied from usbctrl_vendorreq() and pasted here (some 
comments are mine):

/* start of code */
static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void 
*pdata, u16 len, u8 requesttype)
{

/* test if everything is OK for transfers and setup the necessary variables */
[...] 

status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
                                         reqtype, value, 
REALTEK_USB_VENQT_CMD_IDX,
                                         pIo_buf, len, 
RTW_USB_CONTROL_MSG_TIMEOUT);

                if (status == len) {   /*  Success this control transfer. */
                        rtw_reset_continual_urb_error(dvobjpriv);
                        if (requesttype == 0x01)
                                memcpy(pdata, pIo_buf,  len); /* pdata 
receives the read data */
	} else { /*  error cases */

[...]

}
/* end of code */

So, *I cannot ack this RFC*, unless maintainers say I'm missing something.

Larry, Philip, since you have much more knowledge than me about r8188eu (and, 
more in general, on device drivers) may you please say what you think about my 
arguments against this series?

Thanks,

Fabio

> To avoid this type of bugs, i've expanded read() API with error parametr,
> which will be initialized to error if read fails. It helps callers to
> break/return earlier and don't write random values to registers or to rely
> on random values.
> 
> Why is this pacth series RFC?
>   1. I don't have this device and I cannot test these changes.
>   2. I don't know how to handle errors in each particular case. For now, 
function
>      just returns or returns an error. That's all. I hope, driver 
maintainers will
>      help with these bits.
>   3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>      at least half of them
> 
> This series was build-tested and made on top of staging-testing branch
> 
> 
> With regards,
> Pavel Skripkin




^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22  9:53 ` Fabio M. De Francesco
@ 2021-08-22 10:09   ` Pavel Skripkin
  2021-08-22 10:59     ` Fabio M. De Francesco
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 10:09 UTC (permalink / raw)
  To: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux
  Cc: linux-staging, linux-kernel, Martin Kaiser

On 8/22/21 12:53 PM, Fabio M. De Francesco wrote:
> On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
>> Hi, Greg, Larry and Phillip!
>> 
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>> 
>> The first thing I noticed is *no one* was checking read operations result, 
> but
>> it can fail and driver may start writing random stack values into registers. 
> It
>> can cause driver misbehavior or device misbehavior.
> 
> After the messages I wrote yesterday, I had some minutes to look deeper at the
> code that would be changed by these patches.
> 
> I think that it does not look like that the driver could return "random stack
> values into registers" and I think this entire series in unnecessary.
> 
> As far as I understand this driver (though I must admit that I really don't
> know how to write drivers, and I'm not interested in understanding - at the
> moment, at least), all the usb_read*() call usbctrl_vendorreq() and the latter
> *does* proper error checking before returning to the callers the read data.
> 
> Please, look at the code copied from usbctrl_vendorreq() and pasted here (some
> comments are mine):
> 
> /* start of code */
> static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
> *pdata, u16 len, u8 requesttype)
> {
> 
> /* test if everything is OK for transfers and setup the necessary variables */
> [...]
> 
> status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
>                                           reqtype, value,
> REALTEK_USB_VENQT_CMD_IDX,
>                                           pIo_buf, len,
> RTW_USB_CONTROL_MSG_TIMEOUT);
> 
>                  if (status == len) {   /*  Success this control transfer. */
>                          rtw_reset_continual_urb_error(dvobjpriv);
>                          if (requesttype == 0x01)
>                                  memcpy(pdata, pIo_buf,  len); /* pdata
> receives the read data */
> 	} else { /*  error cases */
> 
> [...]
> 
> }
> /* end of code */
> 
> So, *I cannot ack this RFC*, unless maintainers say I'm missing something.
> 
> Larry, Philip, since you have much more knowledge than me about r8188eu (and,
> more in general, on device drivers) may you please say what you think about my
> arguments against this series?
> 

Hi, Fabio!

Thank you for looking into this, but I still can see the case when pdata 
won't be initialized:


pdata is initialized only in case of successful transfer, i.e len > 0. 
It means some data was received (maybe not full length, but anyway). In 
case of usb_control_msg() error (for example -ENOMEM) code only does 
this code block:

if (status < 0) {
	if (status == (-ESHUTDOWN) || status == -ENODEV) {
		adapt->bSurpriseRemoved = true;
	} else {
		struct hal_data_8188e	*haldata = GET_HAL_DATA(adapt);
		haldata->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
	}
}


And then just loops further. In case of 10 ENOMEM in a row,. passed 
pdata won't be initialized at all and driver doesn't do anything about 
it. I believe, it's not good approach to play with random values. We 
should somehow handle transfer errors all across the driver.

If I am missing something, please, let me know :)



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 10:09   ` Pavel Skripkin
@ 2021-08-22 10:59     ` Fabio M. De Francesco
  2021-08-22 11:34       ` Fabio M. De Francesco
  2021-08-22 12:10       ` Pavel Skripkin
  0 siblings, 2 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-22 10:59 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel, Martin Kaiser

On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> On 8/22/21 12:53 PM, Fabio M. De Francesco wrote:
> > On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
> >> Hi, Greg, Larry and Phillip!
> >> 
> >> I noticed, that new staging driver was added like 3 weeks ago and I 
decided
> >> to look at the code, because drivers in staging directory are always 
buggy.
> >> 
> >> The first thing I noticed is *no one* was checking read operations 
result,
> > 
> > but
> > 
> >> it can fail and driver may start writing random stack values into 
registers.
> > 
> > It
> > 
> >> can cause driver misbehavior or device misbehavior.
> > 
> > After the messages I wrote yesterday, I had some minutes to look deeper at 
the
> > code that would be changed by these patches.
> > 
> > I think that it does not look like that the driver could return "random 
stack
> > values into registers" and I think this entire series in unnecessary.
> > 
> > As far as I understand this driver (though I must admit that I really 
don't
> > know how to write drivers, and I'm not interested in understanding - at 
the
> > moment, at least), all the usb_read*() call usbctrl_vendorreq() and the 
latter
> > *does* proper error checking before returning to the callers the read 
data.
> > 
> > Please, look at the code copied from usbctrl_vendorreq() and pasted here 
(some
> > comments are mine):
> > 
> > /* start of code */
> > static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
> > *pdata, u16 len, u8 requesttype)
> > {
> > 
> > /* test if everything is OK for transfers and setup the necessary 
variables */
> > [...]
> > 
> > status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
> > 
> >                                           reqtype, value,
> > 
> > REALTEK_USB_VENQT_CMD_IDX,
> > 
> >                                           pIo_buf, len,
> > 
> > RTW_USB_CONTROL_MSG_TIMEOUT);
> > 
> >                  if (status == len) {   /*  Success this control transfer. 
*/
> >                  
> >                          rtw_reset_continual_urb_error(dvobjpriv);
> >                          if (requesttype == 0x01)
> >                          
> >                                  memcpy(pdata, pIo_buf,  len); /* pdata
> > 
> > receives the read data */
> > 
> > 	} else { /*  error cases */
> > 
> > [...]
> > 
> > }
> > /* end of code */
> > 
> > So, *I cannot ack this RFC*, unless maintainers say I'm missing something.
> > 
> > Larry, Philip, since you have much more knowledge than me about r8188eu 
(and,
> > more in general, on device drivers) may you please say what you think 
about my
> > arguments against this series?
> 
> Hi, Fabio!
> 
> Thank you for looking into this, but I still can see the case when pdata
> won't be initialized:
> 
> 
> pdata is initialized only in case of successful transfer, i.e len > 0.
> It means some data was received (maybe not full length, but anyway). In
> case of usb_control_msg() error (for example -ENOMEM) code only does
> this code block:
> 
> if (status < 0) {
> 	if (status == (-ESHUTDOWN) || status == -ENODEV) {
> 		adapt->bSurpriseRemoved = true;
> 	} else {
> 		struct hal_data_8188e	*haldata = GET_HAL_DATA(adapt);
> 		haldata->srestpriv.Wifi_Error_Status = 
USB_VEN_REQ_CMD_FAIL;
> 	}
> }

It's up to the callers of _rtw_usb*() to check return values and then act 
accordingly. 

It doesn't matter whether or not *pdata is initialized because usb_read*() 
returns data = 0 if usb_control_msg() has not initialized/changed  its third 
parameter. Then _rtw_read*() receive 0 or initialized data depending on errors 
or no errors. Finally _rtw_read*() returns that same value to the callers (via 
r_val). 

So, it's up to the callers to test if (!_rtw_read*()) and then act 
accordingly. If they get 0 they should know how to handle the errors.

Furthermore, we have already either adapt->bSurpriseRemoved = true or haldata-
>srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL. Depending on contexts 
where _rtw_read*() are called, perhaps they could also check the two variables 
above.

In summation. if anything should be changed, it is the code of the callers of 
_rtw_read*() if you find out they they don't properly handle the returning 
values of this function. You should find every place where _rtw_read*() are 
called and figure out if the returns are properly checked and handled; if not, 
make some change only there.

Larry, Philip, where are you? Am I missing something?

Thanks,

Fabio

> 
> And then just loops further. In case of 10 ENOMEM in a row,. passed
> pdata won't be initialized at all and driver doesn't do anything about
> it. I believe, it's not good approach to play with random values. We
> should somehow handle transfer errors all across the driver.
> 
> If I am missing something, please, let me know :)
> 
> 
> 
> With regards,
> Pavel Skripkin





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 10:59     ` Fabio M. De Francesco
@ 2021-08-22 11:34       ` Fabio M. De Francesco
  2021-08-22 12:10       ` Pavel Skripkin
  1 sibling, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-22 11:34 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel, Martin Kaiser

On Sunday, August 22, 2021 12:59:13 PM CEST Fabio M. De Francesco wrote:

> It's up to the callers of _rtw_usb*() to check return values and then act
> accordingly.

Typo.

Replace "_rtw_usb*()" with "_rtw_read*()".

My fault. Sorry :(

Fabio



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 10:59     ` Fabio M. De Francesco
  2021-08-22 11:34       ` Fabio M. De Francesco
@ 2021-08-22 12:10       ` Pavel Skripkin
  2021-08-22 12:39         ` Greg KH
  1 sibling, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 12:10 UTC (permalink / raw)
  To: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux
  Cc: linux-staging, linux-kernel, Martin Kaiser

On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
>> On 8/22/21 12:53 PM, Fabio M. De Francesco wrote:
>> > On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
>> >> Hi, Greg, Larry and Phillip!
>> >> 
>> >> I noticed, that new staging driver was added like 3 weeks ago and I 
> decided
>> >> to look at the code, because drivers in staging directory are always 
> buggy.
>> >> 
>> >> The first thing I noticed is *no one* was checking read operations 
> result,
>> > 
>> > but
>> > 
>> >> it can fail and driver may start writing random stack values into 
> registers.
>> > 
>> > It
>> > 
>> >> can cause driver misbehavior or device misbehavior.
>> > 
>> > After the messages I wrote yesterday, I had some minutes to look deeper at 
> the
>> > code that would be changed by these patches.
>> > 
>> > I think that it does not look like that the driver could return "random 
> stack
>> > values into registers" and I think this entire series in unnecessary.
>> > 
>> > As far as I understand this driver (though I must admit that I really 
> don't
>> > know how to write drivers, and I'm not interested in understanding - at 
> the
>> > moment, at least), all the usb_read*() call usbctrl_vendorreq() and the 
> latter
>> > *does* proper error checking before returning to the callers the read 
> data.
>> > 
>> > Please, look at the code copied from usbctrl_vendorreq() and pasted here 
> (some
>> > comments are mine):
>> > 
>> > /* start of code */
>> > static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
>> > *pdata, u16 len, u8 requesttype)
>> > {
>> > 
>> > /* test if everything is OK for transfers and setup the necessary 
> variables */
>> > [...]
>> > 
>> > status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
>> > 
>> >                                           reqtype, value,
>> > 
>> > REALTEK_USB_VENQT_CMD_IDX,
>> > 
>> >                                           pIo_buf, len,
>> > 
>> > RTW_USB_CONTROL_MSG_TIMEOUT);
>> > 
>> >                  if (status == len) {   /*  Success this control transfer. 
> */
>> >                  
>> >                          rtw_reset_continual_urb_error(dvobjpriv);
>> >                          if (requesttype == 0x01)
>> >                          
>> >                                  memcpy(pdata, pIo_buf,  len); /* pdata
>> > 
>> > receives the read data */
>> > 
>> > 	} else { /*  error cases */
>> > 
>> > [...]
>> > 
>> > }
>> > /* end of code */
>> > 
>> > So, *I cannot ack this RFC*, unless maintainers say I'm missing something.
>> > 
>> > Larry, Philip, since you have much more knowledge than me about r8188eu 
> (and,
>> > more in general, on device drivers) may you please say what you think 
> about my
>> > arguments against this series?
>> 
>> Hi, Fabio!
>> 
>> Thank you for looking into this, but I still can see the case when pdata
>> won't be initialized:
>> 
>> 
>> pdata is initialized only in case of successful transfer, i.e len > 0.
>> It means some data was received (maybe not full length, but anyway). In
>> case of usb_control_msg() error (for example -ENOMEM) code only does
>> this code block:
>> 
>> if (status < 0) {
>> 	if (status == (-ESHUTDOWN) || status == -ENODEV) {
>> 		adapt->bSurpriseRemoved = true;
>> 	} else {
>> 		struct hal_data_8188e	*haldata = GET_HAL_DATA(adapt);
>> 		haldata->srestpriv.Wifi_Error_Status = 
> USB_VEN_REQ_CMD_FAIL;
>> 	}
>> }
> 
> It's up to the callers of _rtw_usb*() to check return values and then act
> accordingly.
> 
> It doesn't matter whether or not *pdata is initialized because usb_read*()
> returns data = 0 if usb_control_msg() has not initialized/changed  its third
> parameter. Then _rtw_read*() receive 0 or initialized data depending on errors
> or no errors. Finally _rtw_read*() returns that same value to the callers (via
> r_val).
> 
> So, it's up to the callers to test if (!_rtw_read*()) and then act
> accordingly. If they get 0 they should know how to handle the errors.
> 

Yes, but _rtw_read*() == 0 indicates 2 states:

	1. Error on transfer side
	2. Actual register value is 0

> Furthermore, we have already either adapt->bSurpriseRemoved = true or haldata-
>>srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL. Depending on contexts 
> where _rtw_read*() are called, perhaps they could also check the two variables
> above.

Yes, Wifi_Error_Status can be used, but it's set every time an error 
occurred. For example if 8th usb_control_msg() was successful 
Wifi_Error_Status will be set to error anyway. It's can be easily fixed, 
of course.

IMO, we should switch to standard way of handling these type of errors 
to move the driver out of staging someday


BTW: syzbot already found uninit value bug in r817xu driver:

https://syzkaller.appspot.com/bug?id=3cd92b1d85428b128503bfa7a250294c9ae00bd8

The usb related code in these drivers is the same, so bugs I am talking 
about are real.

> 
> In summation. if anything should be changed, it is the code of the callers of
> _rtw_read*() if you find out they they don't properly handle the returning
> values of this function. You should find every place where _rtw_read*() are
> called and figure out if the returns are properly checked and handled; if not,
> make some change only there.
> 
> Larry, Philip, where are you? Am I missing something?
> 

I am waiting for their replies too :) I have almost ready v2, so...



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 12:10       ` Pavel Skripkin
@ 2021-08-22 12:39         ` Greg KH
  2021-08-22 12:50           ` Pavel Skripkin
  2021-08-22 13:21           ` Fabio M. De Francesco
  0 siblings, 2 replies; 118+ messages in thread
From: Greg KH @ 2021-08-22 12:39 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Fabio M. De Francesco, Larry.Finger, phil, straube.linux,
	linux-staging, linux-kernel, Martin Kaiser

On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> > > On 8/22/21 12:53 PM, Fabio M. De Francesco wrote:
> > > > On Friday, August 20, 2021 7:07:28 PM CEST Pavel Skripkin wrote:
> > > >> Hi, Greg, Larry and Phillip!
> > > >> >> I noticed, that new staging driver was added like 3 weeks ago
> > > and I
> > decided
> > > >> to look at the code, because drivers in staging directory are
> > > always
> > buggy.
> > > >> >> The first thing I noticed is *no one* was checking read
> > > operations
> > result,
> > > > > but
> > > > >> it can fail and driver may start writing random stack values
> > > into
> > registers.
> > > > > It
> > > > >> can cause driver misbehavior or device misbehavior.
> > > > > After the messages I wrote yesterday, I had some minutes to look
> > > deeper at
> > the
> > > > code that would be changed by these patches.
> > > > > I think that it does not look like that the driver could return
> > > "random
> > stack
> > > > values into registers" and I think this entire series in unnecessary.
> > > > > As far as I understand this driver (though I must admit that I
> > > really
> > don't
> > > > know how to write drivers, and I'm not interested in understanding
> > > - at
> > the
> > > > moment, at least), all the usb_read*() call usbctrl_vendorreq()
> > > and the
> > latter
> > > > *does* proper error checking before returning to the callers the
> > > read
> > data.
> > > > > Please, look at the code copied from usbctrl_vendorreq() and
> > > pasted here
> > (some
> > > > comments are mine):
> > > > > /* start of code */
> > > > static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void
> > > > *pdata, u16 len, u8 requesttype)
> > > > {
> > > > > /* test if everything is OK for transfers and setup the
> > > necessary
> > variables */
> > > > [...]
> > > > > status = usb_control_msg(udev, pipe, REALTEK_USB_VENQT_CMD_REQ,
> > > > >                                           reqtype, value,
> > > > > REALTEK_USB_VENQT_CMD_IDX,
> > > > >                                           pIo_buf, len,
> > > > > RTW_USB_CONTROL_MSG_TIMEOUT);
> > > > >                  if (status == len) {   /*  Success this control
> > > transfer.
> > */
> > > >                  >
> > > rtw_reset_continual_urb_error(dvobjpriv);
> > > >                          if (requesttype == 0x01)
> > > >                          >
> > > memcpy(pdata, pIo_buf,  len); /* pdata
> > > > > receives the read data */
> > > > > 	} else { /*  error cases */
> > > > > [...]
> > > > > }
> > > > /* end of code */
> > > > > So, *I cannot ack this RFC*, unless maintainers say I'm missing
> > > something.
> > > > > Larry, Philip, since you have much more knowledge than me about
> > > r8188eu
> > (and,
> > > > more in general, on device drivers) may you please say what you
> > > think
> > about my
> > > > arguments against this series?
> > > 
> > > Hi, Fabio!
> > > 
> > > Thank you for looking into this, but I still can see the case when pdata
> > > won't be initialized:
> > > 
> > > 
> > > pdata is initialized only in case of successful transfer, i.e len > 0.
> > > It means some data was received (maybe not full length, but anyway). In
> > > case of usb_control_msg() error (for example -ENOMEM) code only does
> > > this code block:
> > > 
> > > if (status < 0) {
> > > 	if (status == (-ESHUTDOWN) || status == -ENODEV) {
> > > 		adapt->bSurpriseRemoved = true;
> > > 	} else {
> > > 		struct hal_data_8188e	*haldata = GET_HAL_DATA(adapt);
> > > 		haldata->srestpriv.Wifi_Error_Status =
> > USB_VEN_REQ_CMD_FAIL;
> > > 	}
> > > }
> > 
> > It's up to the callers of _rtw_usb*() to check return values and then act
> > accordingly.
> > 
> > It doesn't matter whether or not *pdata is initialized because usb_read*()
> > returns data = 0 if usb_control_msg() has not initialized/changed  its third
> > parameter. Then _rtw_read*() receive 0 or initialized data depending on errors
> > or no errors. Finally _rtw_read*() returns that same value to the callers (via
> > r_val).
> > 
> > So, it's up to the callers to test if (!_rtw_read*()) and then act
> > accordingly. If they get 0 they should know how to handle the errors.
> > 
> 
> Yes, but _rtw_read*() == 0 indicates 2 states:
> 
> 	1. Error on transfer side
> 	2. Actual register value is 0

That's not a good design, it should be fixed.  Note there is the new
usb_control_msg_recv() function which should probably be used instead
here, to prevent this problem from happening.

> > In summation. if anything should be changed, it is the code of the callers of
> > _rtw_read*() if you find out they they don't properly handle the returning
> > values of this function. You should find every place where _rtw_read*() are
> > called and figure out if the returns are properly checked and handled; if not,
> > make some change only there.
> > 
> > Larry, Philip, where are you? Am I missing something?

Relax, there is no need to get jumpy, people do not have to respond
instantly to emails here.  Especially when it is not their job to do so.

greg k-h

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 12:39         ` Greg KH
@ 2021-08-22 12:50           ` Pavel Skripkin
  2021-08-22 13:06             ` Greg KH
  2021-08-22 13:21           ` Fabio M. De Francesco
  1 sibling, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 12:50 UTC (permalink / raw)
  To: Greg KH
  Cc: Fabio M. De Francesco, Larry.Finger, phil, straube.linux,
	linux-staging, linux-kernel, Martin Kaiser

On 8/22/21 3:39 PM, Greg KH wrote:
>> 
>> Yes, but _rtw_read*() == 0 indicates 2 states:
>> 
>> 	1. Error on transfer side
>> 	2. Actual register value is 0
> 
> That's not a good design, it should be fixed.  Note there is the new
> usb_control_msg_recv() function which should probably be used instead
> here, to prevent this problem from happening.
> 

Thank you, Greg, for confirmation. That's was the point why I started to 
write this series :)

I think, usb_control_msg_recv() won't help us with this problem, since 
all rtw_read*() functions return an unsigned value now. In future, when 
driver code will be fixed (ex: a lot of void function, which can fail 
and leave passed pointer uninitialized) we can move to new usb API and 
then move driver out of staging :)


With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 12:50           ` Pavel Skripkin
@ 2021-08-22 13:06             ` Greg KH
  0 siblings, 0 replies; 118+ messages in thread
From: Greg KH @ 2021-08-22 13:06 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Fabio M. De Francesco, Larry.Finger, phil, straube.linux,
	linux-staging, linux-kernel, Martin Kaiser

On Sun, Aug 22, 2021 at 03:50:35PM +0300, Pavel Skripkin wrote:
> On 8/22/21 3:39 PM, Greg KH wrote:
> > > 
> > > Yes, but _rtw_read*() == 0 indicates 2 states:
> > > 
> > > 	1. Error on transfer side
> > > 	2. Actual register value is 0
> > 
> > That's not a good design, it should be fixed.  Note there is the new
> > usb_control_msg_recv() function which should probably be used instead
> > here, to prevent this problem from happening.
> > 
> 
> Thank you, Greg, for confirmation. That's was the point why I started to
> write this series :)
> 
> I think, usb_control_msg_recv() won't help us with this problem, since all
> rtw_read*() functions return an unsigned value now. In future, when driver
> code will be fixed (ex: a lot of void function, which can fail and leave
> passed pointer uninitialized) we can move to new usb API and then move
> driver out of staging :)

That function _should_ be used at the lower levels of this call chain.
If you want to go from the top -> down or bottom -> up of fixing this is
your choice, but as others have pointed out, this patch series as-is
still needs some work.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 12:39         ` Greg KH
  2021-08-22 12:50           ` Pavel Skripkin
@ 2021-08-22 13:21           ` Fabio M. De Francesco
  2021-08-22 13:30             ` Greg KH
                               ` (2 more replies)
  1 sibling, 3 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-22 13:21 UTC (permalink / raw)
  To: Pavel Skripkin, Greg KH
  Cc: Larry.Finger, phil, straube.linux, linux-staging, linux-kernel,
	Martin Kaiser

On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
> On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
[...]
> > > So, it's up to the callers to test if (!_rtw_read*()) and then act
> > > accordingly. If they get 0 they should know how to handle the errors.
> > 
> > Yes, but _rtw_read*() == 0 indicates 2 states:
> > 	1. Error on transfer side
> > 	2. Actual register value is 0
> 
> That's not a good design, it should be fixed.  Note there is the new
> usb_control_msg_recv() function which should probably be used instead
> here, to prevent this problem from happening.

I think that no functions should return 0 for signaling FAILURE. If I'm not 
wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on 
FAILURE. Why don't you just fix this?

> > > In summation. if anything should be changed, it is the code of the 
callers of
> > > _rtw_read*() if you find out they they don't properly handle the 
returning
> > > values of this function. You should find every place where _rtw_read*() 
are
> > > called and figure out if the returns are properly checked and handled; 
if not,
> > > make some change only there.
> > > 
> > > Larry, Philip, where are you? Am I missing something?
> 
> Relax, there is no need to get jumpy, people do not have to respond
> instantly to emails here.  Especially when it is not their job to do so.

I should have placed a big smile at the end of the phrase. I was just kidding 
while trying to get their attention. I know there is no hurry and that no one 
has any obligation of this kind. Again, just kidding :)

Thanks,

Fabio

> greg k-h





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 13:21           ` Fabio M. De Francesco
@ 2021-08-22 13:30             ` Greg KH
  2021-08-22 13:31             ` Pavel Skripkin
  2021-08-22 15:04             ` Phillip Potter
  2 siblings, 0 replies; 118+ messages in thread
From: Greg KH @ 2021-08-22 13:30 UTC (permalink / raw)
  To: Fabio M. De Francesco
  Cc: Pavel Skripkin, Larry.Finger, phil, straube.linux, linux-staging,
	linux-kernel, Martin Kaiser

On Sun, Aug 22, 2021 at 03:21:30PM +0200, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
> > On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> > > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> > > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> [...]
> > > > So, it's up to the callers to test if (!_rtw_read*()) and then act
> > > > accordingly. If they get 0 they should know how to handle the errors.
> > > 
> > > Yes, but _rtw_read*() == 0 indicates 2 states:
> > > 	1. Error on transfer side
> > > 	2. Actual register value is 0
> > 
> > That's not a good design, it should be fixed.  Note there is the new
> > usb_control_msg_recv() function which should probably be used instead
> > here, to prevent this problem from happening.
> 
> I think that no functions should return 0 for signaling FAILURE. If I'm not 
> wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on 
> FAILURE. Why don't you just fix this?

Fix what specifically here?  The usb_control_msg() call?  If so, that is
why usb_control_msg_recv() was created, as sometimes you do want to do
what usb_control_msg() does today (see the users in the USB core today
for examples of why this is needed.)

In general, yes, 0 is success, negative is error, and positive is the
number of bytes read/written.

Anyway, let's see the second round of patches here before continuing
this thread...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 13:21           ` Fabio M. De Francesco
  2021-08-22 13:30             ` Greg KH
@ 2021-08-22 13:31             ` Pavel Skripkin
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
  2021-08-22 16:03               ` [PATCH RFC 0/3] " Fabio M. De Francesco
  2021-08-22 15:04             ` Phillip Potter
  2 siblings, 2 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 13:31 UTC (permalink / raw)
  To: Fabio M. De Francesco, Greg KH
  Cc: Larry.Finger, phil, straube.linux, linux-staging, linux-kernel,
	Martin Kaiser

On 8/22/21 4:21 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
>> On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
>> > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
>> > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> [...]
>> > > So, it's up to the callers to test if (!_rtw_read*()) and then act
>> > > accordingly. If they get 0 they should know how to handle the errors.
>> > 
>> > Yes, but _rtw_read*() == 0 indicates 2 states:
>> > 	1. Error on transfer side
>> > 	2. Actual register value is 0
>> 
>> That's not a good design, it should be fixed.  Note there is the new
>> usb_control_msg_recv() function which should probably be used instead
>> here, to prevent this problem from happening.
> 
> I think that no functions should return 0 for signaling FAILURE. If I'm not
> wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
> FAILURE. Why don't you just fix this?
> 

That's what I've done in v2. All rtw_read* family will have following 
prototype in v2:

int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);


Was it your idea, or you were talking about different approach?


With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 13:31             ` Pavel Skripkin
@ 2021-08-22 14:35               ` Pavel Skripkin
  2021-08-22 14:35                 ` [PATCH RFC v2 1/6] staging: r8188eu: remove {read,write}_macreg Pavel Skripkin
                                   ` (8 more replies)
  2021-08-22 16:03               ` [PATCH RFC 0/3] " Fabio M. De Francesco
  1 sibling, 9 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 14:35 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

Hi, Greg, Larry and Phillip!

I noticed, that new staging driver was added like 3 weeks ago and I decided
to look at the code, because drivers in staging directory are always buggy.

The first thing I noticed is *no one* was checking read operations result, but
it can fail and driver may start writing random stack values into registers. It
can cause driver misbehavior or device misbehavior.

To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
funtions return an error, when something went wrong with usb transfer.

It helps callers to break/return earlier and don't write random values to
registers or to rely on random values.

Why is this pacth series RFC?
  1. I don't have this device and I cannot test these changes.
  2. I don't know how to handle errors in each particular case. For now, function
     just returns or returns an error. That's all. I hope, driver maintainers will
     help with these bits.
  3. I guess, I handled not all uninit value bugs here. I hope, I fixed
     at least half of them


v1 -> v2:
  1. Make rtw_read*() return an error instead of initializing pointer to error
  2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
     changes
  3. Add new macro for printing register values (It helps to not copy-paste error
     handling)
  4. Removed {read,write}_macreg (Suggested by Phillip)
  5. Rebased on top of staging-next
  6. Cleaned checkpatch errors and warnings

Only build-tested, since I don't have device with r8118eu chip

Pavel Skripkin (6):
  staging: r8188eu: remove {read,write}_macreg
  staging: r8188eu: add helper macro for printing registers
  staging: r8188eu: add error handling of rtw_read8
  staging: r8188eu: add error handling of rtw_read16
  staging: r8188eu: add error handling of rtw_read32
  staging: r8188eu: make ReadEFuse return an int

 drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
 drivers/staging/r8188eu/core/rtw_efuse.c      | 125 +++--
 drivers/staging/r8188eu/core/rtw_io.c         |  27 +-
 drivers/staging/r8188eu/core/rtw_mp.c         |  70 ++-
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  13 +-
 drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   5 +-
 drivers/staging/r8188eu/core/rtw_sreset.c     |   9 +-
 .../r8188eu/hal/Hal8188ERateAdaptive.c        |   8 +-
 drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |  21 +-
 drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
 drivers/staging/r8188eu/hal/hal_com.c         |  23 +-
 drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
 drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  33 +-
 drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 285 +++++++++---
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  27 +-
 drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  22 +-
 drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  18 +-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 439 +++++++++++++++---
 drivers/staging/r8188eu/hal/usb_ops_linux.c   |  57 ++-
 drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
 .../staging/r8188eu/include/odm_interface.h   |   6 +-
 .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
 drivers/staging/r8188eu/include/rtw_debug.h   |  13 +
 drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
 drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
 drivers/staging/r8188eu/include/rtw_mp.h      |   2 -
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 179 +++++--
 drivers/staging/r8188eu/os_dep/usb_intf.c     |   3 +-
 30 files changed, 1138 insertions(+), 389 deletions(-)

-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC v2 1/6] staging: r8188eu: remove {read,write}_macreg
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
@ 2021-08-22 14:35                 ` Pavel Skripkin
  2021-08-22 14:35                 ` [PATCH RFC v2 2/6] staging: r8188eu: add helper macro for printing registers Pavel Skripkin
                                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 14:35 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

These 2 functions are unused, so they can be simply removed

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_mp.c    | 39 ------------------------
 drivers/staging/r8188eu/include/rtw_mp.h |  2 --
 2 files changed, 41 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 93bb683b628f..0a0a24fd37b0 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -7,45 +7,6 @@
 #include "../include/odm_precomp.h"
 #include "../include/rtl8188e_hal.h"
 
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
-{
-	u32 val = 0;
-
-	switch (sz) {
-	case 1:
-		val = rtw_read8(padapter, addr);
-		break;
-	case 2:
-		val = rtw_read16(padapter, addr);
-		break;
-	case 4:
-		val = rtw_read32(padapter, addr);
-		break;
-	default:
-		val = 0xffffffff;
-		break;
-	}
-
-	return val;
-}
-
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz)
-{
-	switch (sz) {
-	case 1:
-		rtw_write8(padapter, addr, (u8)val);
-		break;
-	case 2:
-		rtw_write16(padapter, addr, (u16)val);
-		break;
-	case 4:
-		rtw_write32(padapter, addr, val);
-		break;
-	default:
-		break;
-	}
-}
-
 u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask)
 {
 	return rtw_hal_read_bbreg(padapter, addr, bitmask);
diff --git a/drivers/staging/r8188eu/include/rtw_mp.h b/drivers/staging/r8188eu/include/rtw_mp.h
index b64b16554343..3a259d991348 100644
--- a/drivers/staging/r8188eu/include/rtw_mp.h
+++ b/drivers/staging/r8188eu/include/rtw_mp.h
@@ -410,8 +410,6 @@ void mp_stop_test(struct adapter *padapter);
 u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask);
 void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val);
 
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz);
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz);
 u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask);
 void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val);
 u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr);
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC v2 2/6] staging: r8188eu: add helper macro for printing registers
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
  2021-08-22 14:35                 ` [PATCH RFC v2 1/6] staging: r8188eu: remove {read,write}_macreg Pavel Skripkin
@ 2021-08-22 14:35                 ` Pavel Skripkin
  2021-08-22 14:35                 ` [PATCH RFC v2 3/6] staging: r8188eu: add error handling of rtw_read8 Pavel Skripkin
                                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 14:35 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

There are a lof of places, where DBG_88E() is used to print register
value. Since following patches change _rtw_read*() family
prototypes, we can wrap printing registers into useful macro to avoid
open-coding error checking like this:

	u32 tmp;
	if (!rtw_read(&tmp))
		DBG("reg = %d\n", tmp);

So, added DBG_88E_REG{8,16,32} macros for printing register values.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/include/rtw_debug.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/staging/r8188eu/include/rtw_debug.h b/drivers/staging/r8188eu/include/rtw_debug.h
index 3c3bf2a4f30e..059647b9cd3a 100644
--- a/drivers/staging/r8188eu/include/rtw_debug.h
+++ b/drivers/staging/r8188eu/include/rtw_debug.h
@@ -72,6 +72,19 @@ extern u32 GlobalDebugLevel;
 			pr_info(DRIVER_PREFIX __VA_ARGS__);			\
 	} while (0)
 
+#define __DBG_88E_REG(fmt, adap, reg, size)				\
+	do {								\
+		u##size __tmp__;					\
+		if (rtw_read##size((adap), (reg), &__tmp__))		\
+			break;						\
+		if (_drv_err_ <= GlobalDebugLevel)			\
+			pr_info(DRIVER_PREFIX fmt, __tmp__);		\
+	} while (0)
+
+#define DBG_88E_REG8(fmt, adap, reg)	__DBG_88E_REG(fmt, adap, reg, 8)
+#define DBG_88E_REG16(fmt, adap, reg)	__DBG_88E_REG(fmt, adap, reg, 16)
+#define DBG_88E_REG32(fmt, adap, reg)	__DBG_88E_REG(fmt, adap, reg, 32)
+
 int proc_get_drv_version(char *page, char **start,
 			 off_t offset, int count,
 			 int *eof, void *data);
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC v2 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
  2021-08-22 14:35                 ` [PATCH RFC v2 1/6] staging: r8188eu: remove {read,write}_macreg Pavel Skripkin
  2021-08-22 14:35                 ` [PATCH RFC v2 2/6] staging: r8188eu: add helper macro for printing registers Pavel Skripkin
@ 2021-08-22 14:35                 ` Pavel Skripkin
  2021-08-22 14:35                 ` [PATCH RFC v2 4/6] staging: r8188eu: add error handling of rtw_read16 Pavel Skripkin
                                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 14:35 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

_rtw_read8 function can fail in case of usb transfer failure. But
previous function prototype wasn't designed to return an error to
caller. It can cause a lot uninit value bugs all across the driver code,
since rtw_read8() returns local stack variable to caller.

Fix it by changing the prototype of this function. Now it returns an
int: 0 on success, negative error value on failure and callers should pass
the pointer to storage location for register value.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_debug.c      |  11 +-
 drivers/staging/r8188eu/core/rtw_efuse.c      |  76 +++--
 drivers/staging/r8188eu/core/rtw_io.c         |   9 +-
 drivers/staging/r8188eu/core/rtw_mp.c         |  13 +-
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |   5 +-
 drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |  19 +-
 drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
 drivers/staging/r8188eu/hal/hal_com.c         |  23 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |   4 +-
 drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  33 ++-
 drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 128 +++++++--
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  10 +-
 drivers/staging/r8188eu/hal/rtl8188e_sreset.c |   8 +-
 drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  18 +-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 267 +++++++++++++++---
 drivers/staging/r8188eu/hal/usb_ops_linux.c   |  19 +-
 .../staging/r8188eu/include/odm_interface.h   |   2 +-
 drivers/staging/r8188eu/include/rtw_io.h      |   6 +-
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  |  61 +++-
 20 files changed, 569 insertions(+), 158 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 2ee64cef73f7..8b7d3eb12bd0 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -73,8 +73,8 @@ int proc_get_read_reg(char *page, char **start,
 {
 	struct net_device *dev = data;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
-	int len = 0;
+	u32 tmp;
+	int len = 0, error;
 
 	if (proc_get_read_addr == 0xeeeeeeee) {
 		*eof = 1;
@@ -83,7 +83,12 @@ int proc_get_read_reg(char *page, char **start,
 
 	switch (proc_get_read_len) {
 	case 1:
-		len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr));
+		error = rtw_read8(padapter, proc_get_read_addr, (u8 *) &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n",
+				proc_get_read_addr, (u8) tmp);
 		break;
 	case 2:
 		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index decccf7622f0..b471f6446f78 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -159,6 +159,7 @@ ReadEFuseByte(
 	u32 value32;
 	u8 readbyte;
 	u16 retry;
+	int error;
 
 	if (pseudo) {
 		Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
@@ -167,11 +168,17 @@ ReadEFuseByte(
 
 	/* Write Address */
 	rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
-	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);
+	error = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
 
 	/* Write bit 32 0 */
-	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3);
+	error = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
 
 	/* Check bit 32 read-ready */
@@ -244,6 +251,7 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
 	u8 temp = {0x00};
 	u32 k = 0;
 	u16 contentLen = 0;
+	int error;
 
 	EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
 
@@ -251,27 +259,42 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
 		/* Write E-fuse Register address bit0~7 */
 		temp = Address & 0xFF;
 		rtw_write8(Adapter, EFUSE_CTRL + 1, temp);
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2);
+		error = rtw_read8(Adapter, EFUSE_CTRL + 2, &Bytetemp);
+		if (error)
+			return 0xFF;
+
 		/* Write E-fuse Register address bit8~9 */
 		temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
 		rtw_write8(Adapter, EFUSE_CTRL + 2, temp);
 
 		/* Write 0x30[31]= 0 */
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+		error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
+		if (error)
+			return 0xFF;
+
 		temp = Bytetemp & 0x7F;
 		rtw_write8(Adapter, EFUSE_CTRL + 3, temp);
 
 		/* Wait Write-ready (0x30[31]= 1) */
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+		error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
+		if (error)
+			return 0xFF;
+
 		while (!(Bytetemp & 0x80)) {
-			Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+			error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
+			if (error)
+				return 0xFF;
+
 			k++;
 			if (k == 1000) {
 				k = 0;
 				break;
 			}
 		}
-		data = rtw_read8(Adapter, EFUSE_CTRL);
+		error = rtw_read8(Adapter, EFUSE_CTRL, &data);
+		if (error)
+			return 0xFF;
+
 		return data;
 	} else {
 		return 0xFF;
@@ -284,6 +307,8 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
 {
 	u8 tmpidx = 0;
 	u8 result;
+	u8 tmp;
+	int error;
 
 	if (pseudo) {
 		result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
@@ -292,16 +317,25 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
 	/*  -----------------e-fuse reg ctrl --------------------------------- */
 	/* address */
 	rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
-	rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
-		   (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
+	error = rtw_read8(pAdapter, EFUSE_CTRL + 2, &tmp);
+	if (error)
+		return false;
 
+	rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | (tmp & 0xFC));
 	rtw_write8(pAdapter, EFUSE_CTRL + 3,  0x72);/* read cmd */
 
-	while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
-		tmpidx++;
+	do {
+		error = rtw_read8(pAdapter, EFUSE_CTRL + 3, &tmp);
+		if (error)
+			return false;
+	} while (!(0x80 & tmp) && (++tmpidx < 100));
+
 	if (tmpidx < 100) {
-		*data = rtw_read8(pAdapter, EFUSE_CTRL);
-		result = true;
+		error = rtw_read8(pAdapter, EFUSE_CTRL, data);
+		if (error)
+			result = false;
+		else
+			result = true;
 	} else {
 		*data = 0xff;
 		result = false;
@@ -314,6 +348,8 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
 {
 	u8 tmpidx = 0;
 	u8 result;
+	u8 tmp;
+	int error;
 
 	if (pseudo) {
 		result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
@@ -323,15 +359,23 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
 	/*  -----------------e-fuse reg ctrl --------------------------------- */
 	/* address */
 	rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
+
+	error = rtw_read8(pAdapter, EFUSE_CTRL + 2, &tmp);
+	if (error)
+		return false;
+
 	rtw_write8(pAdapter, EFUSE_CTRL + 2,
-		   (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) |
+		   (tmp & 0xFC) |
 		   (u8)((addr >> 8) & 0x03));
 	rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */
 
 	rtw_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);/* write cmd */
 
-	while ((0x80 &  rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
-		tmpidx++;
+	do {
+		error = rtw_read8(pAdapter, EFUSE_CTRL + 3, &tmp);
+		if (error)
+			return false;
+	} while (!(0x80 & tmp) && (++tmpidx < 100));
 
 	if (tmpidx < 100)
 		result = true;
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index cde0205816b1..2714506c8ffb 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -34,18 +34,15 @@ jackson@realtek.com.tw
 #define rtw_cpu_to_le16(val)		cpu_to_le16(val)
 #define rtw_cpu_to_le32(val)		cpu_to_le32(val)
 
-u8 _rtw_read8(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
 {
-	u8 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl *pintfhdl = &pio_priv->intf;
-	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
-
+	int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
 
 	_read8 = pintfhdl->io_ops._read8;
-	r_val = _read8(pintfhdl, addr);
 
-	return r_val;
+	return _read8(pintfhdl, addr, data);
 }
 
 u16 _rtw_read16(struct adapter *adapter, u32 addr)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 0a0a24fd37b0..76f0bc399819 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -243,10 +243,14 @@ void GetPowerTracking(struct adapter *padapter, u8 *enable)
 static void disable_dm(struct adapter *padapter)
 {
 	u8 v8;
+	int error;
 
 	/* 3 1. disable firmware dynamic mechanism */
 	/*  disable Power Training, Rate Adaptive */
-	v8 = rtw_read8(padapter, REG_BCN_CTRL);
+	error = rtw_read8(padapter, REG_BCN_CTRL, &v8);
+	if (error)
+		return;
+
 	v8 &= ~EN_BCN_FUNCTION;
 	rtw_write8(padapter, REG_BCN_CTRL, v8);
 
@@ -363,8 +367,13 @@ s32 mp_start_test(struct adapter *padapter)
 	spin_unlock_bh(&pmlmepriv->lock);
 
 	if (res == _SUCCESS) {
+		int error;
 		/*  set MSR to WIFI_FW_ADHOC_STATE */
-		val8 = rtw_read8(padapter, MSR) & 0xFC; /*  0x0102 */
+		error = rtw_read8(padapter, MSR, &val8); /*  0x0102 */
+		if (error)
+			return _FAIL;
+
+		val8 &= 0xFC;
 		val8 |= WIFI_FW_ADHOC_STATE;
 		rtw_write8(padapter, MSR, val8); /*  Link in ad hoc network */
 	}
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c85f8e467337..894ab456f202 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -632,6 +632,7 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 	u32		offset, width;
 	int status = NDIS_STATUS_SUCCESS;
 	struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
+	int error;
 
 	if (poid_par_priv->type_of_oid != QUERY_OID)
 		return NDIS_STATUS_NOT_ACCEPTED;
@@ -647,7 +648,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 
 	switch (width) {
 	case 1:
-		RegRWStruct->value = rtw_read8(Adapter, offset);
+		error = rtw_read8(Adapter, offset, (u8 *) &RegRWStruct->value);
+		if (error)
+			status = NDIS_STATUS_NOT_ACCEPTED;
 		break;
 	case 2:
 		RegRWStruct->value = rtw_read16(Adapter, offset);
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index 356885e27edd..3545ad60dc00 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -660,8 +660,12 @@ static void _PHY_SaveMACRegisters(
 	u32 i;
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(adapt);
 	struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
+	int error;
+
 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
-		MACBackup[i] = ODM_Read1Byte(dm_odm, MACReg[i]);
+		error = ODM_Read1Byte(dm_odm, MACReg[i], (u8 *) &MACBackup[i]);
+		if (error)
+			return;
 	}
 	MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
 }
@@ -1010,9 +1014,12 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
 	u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(adapt);
 	struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
+	int error;
 
 	/* Check continuous TX and Packet TX */
-	tmpreg = ODM_Read1Byte(dm_odm, 0xd03);
+	error = ODM_Read1Byte(dm_odm, 0xd03, &tmpreg);
+	if (error)
+		return;
 
 	if ((tmpreg & 0x70) != 0)			/* Deal with contisuous TX case */
 		ODM_Write1Byte(dm_odm, 0xd03, tmpreg & 0x8F);	/* disable all continuous TX */
@@ -1232,7 +1239,13 @@ static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2
 
 	if (!adapt->hw_init_completed) {
 		u8 u1btmp;
-		u1btmp = ODM_Read1Byte(dm_odm, REG_LEDCFG2) | BIT(7);
+		int error;
+
+		error = ODM_Read1Byte(dm_odm, REG_LEDCFG2, &u1btmp);
+		if (error)
+			return;
+
+		u1btmp |= BIT(7);
 		ODM_Write1Byte(dm_odm, REG_LEDCFG2, u1btmp);
 		ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
 	}
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
index 0fd11aca7ac7..74e83381ef06 100644
--- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
@@ -35,6 +35,7 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 	u32 offset = 0;
 	u32 poll_count = 0; /*  polling autoload done. */
 	u32 max_poll_count = 5000;
+	int error;
 
 	do {
 		pwrcfgcmd = pwrseqcmd[aryidx];
@@ -48,7 +49,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
 
 				/*  Read the value from system register */
-				value = rtw_read8(padapter, offset);
+				error = rtw_read8(padapter, offset, &value);
+				if (error)
+					return false;
 
 				value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
 				value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
@@ -60,7 +63,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 				poll_bit = false;
 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
 				do {
-					value = rtw_read8(padapter, offset);
+					error = rtw_read8(padapter, offset, &value);
+					if (error)
+						return false;
 
 					value &= GET_PWR_CFG_MASK(pwrcfgcmd);
 					if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c
index f09d4d49b159..833c88c85e3f 100644
--- a/drivers/staging/r8188eu/hal/hal_com.c
+++ b/drivers/staging/r8188eu/hal/hal_com.c
@@ -321,11 +321,14 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
 	struct c2h_evt_hdr *c2h_evt;
 	int i;
 	u8 trigger;
+	int error;
 
 	if (!buf)
 		goto exit;
 
-	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
+	error = rtw_read8(adapter, REG_C2HEVT_CLEAR, &trigger);
+	if (error)
+		goto exit;
 
 	if (trigger == C2H_EVT_HOST_CLOSE)
 		goto exit; /* Not ready */
@@ -336,13 +339,21 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
 
 	memset(c2h_evt, 0, 16);
 
-	*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
-	*(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
+	error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, buf);
+	if (error)
+		goto clear_evt;
+
+	error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, buf + 1);
+	if (error)
+		goto clear_evt;
 
 	/* Read the content */
-	for (i = 0; i < c2h_evt->plen; i++)
-		c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
-						sizeof(*c2h_evt) + i);
+	for (i = 0; i < c2h_evt->plen; i++) {
+		error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + sizeof(*c2h_evt) + i,
+				  c2h_evt->payload + i);
+		if (error)
+			goto clear_evt;
+	}
 
 	ret = _SUCCESS;
 
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 5a01495d74bc..9a9df98da727 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -4,10 +4,10 @@
 #include "../include/odm_precomp.h"
 /*  ODM IO Relative API. */
 
-u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read8(Adapter, RegAddr);
+	return rtw_read8(Adapter, RegAddr, data);
 }
 
 u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
index 3e1a45030bc8..53636c0e4786 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
@@ -21,12 +21,14 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
 {
 	u8 read_down = false;
 	int	retry_cnts = 100;
-
+	int error;
 	u8 valid;
 
 	do {
-		valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
-		if (0 == valid)
+		error = rtw_read8(adapt, REG_HMETFR, &valid);
+		if (error)
+			return read_down;
+		else if (!(valid & BIT(msgbox_num)))
 			read_down = true;
 	} while ((!read_down) && (retry_cnts--));
 
@@ -578,8 +580,9 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
 	bool	bSendBeacon = false;
 	bool	bcn_valid = false;
-	u8 DLBcnCount = 0;
+	u8 DLBcnCount = 0, val8;
 	u32 poll = 0;
+	int error;
 
 	DBG_88E("%s mstatus(%x)\n", __func__, mstatus);
 
@@ -596,8 +599,15 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 		/*  Disable Hw protection for a time which revserd for Hw sending beacon. */
 		/*  Fix download reserved page packet fail that access collision with the protection time. */
 		/*  2010.05.11. Added by tynli. */
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3)));
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4));
+		error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+		if (error)
+			return;
+		rtw_write8(adapt, REG_BCN_CTRL, val8 & (~BIT(3)));
+
+		error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+		if (error)
+			return;
+		rtw_write8(adapt, REG_BCN_CTRL, val8 | BIT(4));
 
 		if (haldata->RegFwHwTxQCtrl & BIT(6)) {
 			DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
@@ -639,8 +649,15 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 		/*  */
 
 		/*  Enable Bcn */
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3));
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4)));
+		error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+		if (error)
+			return;
+		rtw_write8(adapt, REG_BCN_CTRL, val8 | BIT(3));
+
+		error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+		if (error)
+			return;
+		rtw_write8(adapt, REG_BCN_CTRL, val8 & (~BIT(4)));
 
 		/*  To make sure that if there exists an adapter which would like to send beacon. */
 		/*  If exists, the origianl value of 0x422[6] will be 1, we should check this to */
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
index 78552303c990..5cb3d6369449 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
@@ -16,8 +16,12 @@ static void dm_CheckStatistics(struct adapter *Adapter)
 static void dm_InitGPIOSetting(struct adapter *Adapter)
 {
 	u8	tmp1byte;
+	int error;
+
+	error = rtw_read8(Adapter, REG_GPIO_MUXCFG, &tmp1byte);
+	if (error)
+		return;
 
-	tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
 	tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
 
 	rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 393969f51206..cfc429965b7d 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -13,10 +13,14 @@
 static void iol_mode_enable(struct adapter *padapter, u8 enable)
 {
 	u8 reg_0xf0 = 0;
+	int error;
 
 	if (enable) {
 		/* Enable initial offload */
-		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+		error = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
 
 		if (!padapter->bFWReady) {
@@ -26,7 +30,10 @@ static void iol_mode_enable(struct adapter *padapter, u8 enable)
 
 	} else {
 		/* disable initial offload */
-		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+		error = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
 	}
 }
@@ -35,19 +42,28 @@ static s32 iol_execute(struct adapter *padapter, u8 control)
 {
 	s32 status = _FAIL;
 	u8 reg_0x88 = 0;
-	u32 start = 0, passing_time = 0;
+	u32 start = 0;
+	int error;
 
 	control = control & 0x0f;
-	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+	error = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+	if (error)
+		return status;
+
 	rtw_write8(padapter, REG_HMEBOX_E0,  reg_0x88 | control);
 
 	start = jiffies;
-	while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
-	       (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
-		;
-	}
 
-	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+	do {
+		error = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+		if (error)
+			return status;
+	} while (reg_0x88 & control && rtw_get_passing_time_ms(start) < 1000);
+
+	error = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+	if (error)
+		return status;
+
 	status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
 	if (reg_0x88 & control << 4)
 		status = _FAIL;
@@ -195,17 +211,20 @@ static void efuse_read_phymap_from_txpktbuf(
 	)
 {
 	u16 dbg_addr = 0;
-	u32 start  = 0, passing_time = 0;
+	u32 start  = 0;
 	u8 reg_0x143 = 0;
 	__le32 lo32 = 0, hi32 = 0;
 	u16 len = 0, count = 0;
 	int i = 0;
 	u16 limit = *size;
-
+	int error;
 	u8 *pos = content;
 
-	if (bcnhead < 0) /* if not valid */
-		bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
+	if (bcnhead < 0) { /* if not valid */
+		error = rtw_read8(adapter, REG_TDECTRL + 1, (u8 *) &bcnhead);
+		if (error)
+			return;
+	}
 
 	DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
 
@@ -218,11 +237,21 @@ static void efuse_read_phymap_from_txpktbuf(
 
 		rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
 		start = jiffies;
-		while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
-		       (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
-			DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
+
+		do {
+			u8 tmp;
+
+			error = rtw_read8(adapter, REG_TXPKTBUF_DBG, &reg_0x143);
+			if (error)
+				return;
+
+			if (!rtw_read8(adapter, 0x106, &tmp))
+				DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n",
+					__func__, reg_0x143, tmp);
+
 			rtw_usleep_os(100);
-		}
+		} while (!reg_0x143 && rtw_get_passing_time_ms(start) < 1000);
+
 
 		/* data from EEPROM needs to be in LE */
 		lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
@@ -371,18 +400,28 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 static void _FWDownloadEnable(struct adapter *padapter, bool enable)
 {
 	u8 tmp;
+	int error;
 
 	if (enable) {
 		/*  MCU firmware download enable. */
-		tmp = rtw_read8(padapter, REG_MCUFWDL);
+		error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
 
 		/*  8051 reset */
-		tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
+		error = rtw_read8(padapter, REG_MCUFWDL + 2, &tmp);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
 	} else {
 		/*  MCU firmware download disable. */
-		tmp = rtw_read8(padapter, REG_MCUFWDL);
+		error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
 
 		/*  Reserved for fw extension. */
@@ -452,8 +491,14 @@ static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size
 {
 	u8 value8;
 	u8 u8Page = (u8)(page & 0x07);
+	int error;
 
-	value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
+	error = rtw_read8(padapter, REG_MCUFWDL + 2, &value8);
+	if (error)
+		return error;
+
+	value8 &= 0xF8;
+	value8 |= u8Page;
 	rtw_write8(padapter, REG_MCUFWDL + 2, value8);
 
 	return _BlockWrite(padapter, buffer, size);
@@ -493,8 +538,12 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
 void _8051Reset88E(struct adapter *padapter)
 {
 	u8 u1bTmp;
+	int error;
+
+	error = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &u1bTmp);
+	if (error)
+		return;
 
-	u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
 	rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2)));
 	rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2)));
 	DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
@@ -582,7 +631,7 @@ static int load_firmware(struct rt_firmware *pFirmware, struct device *device)
 s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 {
 	s32	rtStatus = _SUCCESS;
-	u8 writeFW_retry = 0;
+	u8 writeFW_retry = 0, tmp;
 	u32 fwdl_start_time;
 	struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
@@ -591,6 +640,7 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 	u8 *pFirmwareBuf;
 	u32 FirmwareLen;
 	static int log_version;
+	int error;
 
 	if (!dvobj->firmware.szFwBuffer)
 		rtStatus = load_firmware(&dvobj->firmware, device);
@@ -621,7 +671,10 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 
 	/*  Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
 	/*  or it will cause download Fw fail. 2010.02.01. by tynli. */
-	if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+	error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+	if (error) {
+		return _FAIL;
+	} else if (tmp & RAM_DL_SEL) { /* 8051 RAM code */
 		rtw_write8(padapter, REG_MCUFWDL, 0x00);
 		_8051Reset88E(padapter);
 	}
@@ -630,7 +683,11 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 	fwdl_start_time = jiffies;
 	while (1) {
 		/* reset the FWDL chksum */
-		rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
+		error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+		if (error)
+			return _FAIL;
+
+		rtw_write8(padapter, REG_MCUFWDL, tmp | FWDL_ChkSum_rpt);
 
 		rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
 
@@ -715,6 +772,7 @@ hal_EfusePowerSwitch_RTL8188E(
 {
 	u8 tempval;
 	u16	tmpV16;
+	int error;
 
 	if (PwrState) {
 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
@@ -741,7 +799,10 @@ hal_EfusePowerSwitch_RTL8188E(
 
 		if (bWrite) {
 			/*  Enable LDO 2.5V before read/write action */
-			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+			error = rtw_read8(pAdapter, EFUSE_TEST + 3, &tempval);
+			if (error)
+				return;
+
 			tempval &= 0x0F;
 			tempval |= (VOLTAGE_V25 << 4);
 			rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
@@ -751,7 +812,9 @@ hal_EfusePowerSwitch_RTL8188E(
 
 		if (bWrite) {
 			/*  Disable LDO 2.5V after read/write action */
-			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+			error = rtw_read8(pAdapter, EFUSE_TEST + 3, &tempval);
+			if (error)
+				return;
 			rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
 		}
 	}
@@ -1784,12 +1847,19 @@ void rtl8188e_stop_thread(struct adapter *padapter)
 
 static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
 {
+	int error;
+	u8 tmp;
+
+	error = rtw_read8(adapter, rOFDM0_RxDSP + 1, &tmp);
+	if (error)
+		return;
+
 	if (enable) {
 		DBG_88E("Enable notch filter\n");
-		rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
+		rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp | BIT(1));
 	} else {
 		DBG_88E("Disable notch filter\n");
-		rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
+		rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp & ~BIT(1));
 	}
 }
 void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 30a9dca8f453..f6d4c91a97a2 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -960,6 +960,7 @@ _PHY_SetBWMode92C(
 	struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
 	u8 regBwOpMode;
 	u8 regRRSR_RSC;
+	int error;
 
 	if (pHalData->rf_chip == RF_PSEUDO_11N)
 		return;
@@ -975,8 +976,13 @@ _PHY_SetBWMode92C(
 	/* 3<1>Set MAC register */
 	/* 3 */
 
-	regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
-	regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2);
+	error = rtw_read8(Adapter, REG_BWOPMODE, &regBwOpMode);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_RRSR + 2, &regRRSR_RSC);
+	if (error)
+		return;
 
 	switch (pHalData->CurrentChannelBW) {
 	case HT_CHANNEL_WIDTH_20:
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 16fa249e35d3..39dacfb23570 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -49,13 +49,17 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
 {
 	u32 rx_dma_status = 0;
 	u8 fw_status = 0;
+	int error;
+
 	rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
 	if (rx_dma_status != 0x00) {
 		DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
 		rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
 	}
-	fw_status = rtw_read8(padapter, REG_FMETHR);
-	if (fw_status != 0x00) {
+	error = rtw_read8(padapter, REG_FMETHR, &fw_status);
+	if (error) {
+		return;
+	} else if (fw_status != 0x00) {
 		if (fw_status == 1)
 			DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status);
 		else if (fw_status == 2)
diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_led.c b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
index 452d4bb87aba..7f793b7ce609 100644
--- a/drivers/staging/r8188eu/hal/rtl8188eu_led.c
+++ b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
@@ -14,10 +14,15 @@
 void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
 {
 	u8	LedCfg;
+	int error;
 
 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
 		return;
-	LedCfg = rtw_read8(padapter, REG_LEDCFG2);
+
+	error = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);
+	if (error)
+		return;
+
 	switch (pLed->LedPin) {
 	case LED_PIN_LED0:
 		rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /*  SW control led0 on. */
@@ -37,11 +42,14 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
 {
 	u8	LedCfg;
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
+	int error;
 
 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
 		goto exit;
 
-	LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+	error = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);/* 0x4E */
+	if (error)
+		return;
 
 	switch (pLed->LedPin) {
 	case LED_PIN_LED0:
@@ -49,7 +57,11 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
 			/*  Open-drain arrangement for controlling the LED) */
 			LedCfg &= 0x90; /*  Set to software control. */
 			rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
-			LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+
+			error = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &LedCfg);
+			if (error)
+				return;
+
 			LedCfg &= 0xFE;
 			rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
 		} else {
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 5cdabf43d4fd..4f1d7f9b43c3 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -120,6 +120,7 @@ static void _InitInterrupt(struct adapter *Adapter)
 	u32 imr, imr_ex;
 	u8  usb_opt;
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
+	int error;
 
 	/* HISR write one to clear */
 	rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
@@ -135,7 +136,9 @@ static void _InitInterrupt(struct adapter *Adapter)
 	/*  REG_USB_SPECIAL_OPTION - BIT(4) */
 	/*  0; Use interrupt endpoint to upload interrupt pkt */
 	/*  1; Use bulk endpoint to upload interrupt pkt, */
-	usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+	error = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &usb_opt);
+	if (error)
+		return;
 
 	if (!adapter_to_dvobj(Adapter)->ishighspeed)
 		usb_opt = usb_opt & (~INT_BULK_SEL);
@@ -435,8 +438,12 @@ static void _InitRxSetting(struct adapter *Adapter)
 static void _InitRetryFunction(struct adapter *Adapter)
 {
 	u8 value8;
+	int error;
+
+	error = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL, &value8);
+	if (error)
+		return;
 
-	value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
 	value8 |= EN_AMPDU_RTY_NEW;
 	rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
 
@@ -499,9 +506,15 @@ usb_AggSettingRxUpdate(
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	u8 valueDMA;
 	u8 valueUSB;
+	int error;
 
-	valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
-	valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+	error = rtw_read8(Adapter, REG_TRXDMA_CTRL, &valueDMA);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &valueUSB);
+	if (error)
+		return;
 
 	switch (haldata->UsbRxAggMode) {
 	case USB_RX_AGG_DMA:
@@ -589,6 +602,7 @@ static void _InitOperationMode(struct adapter *Adapter)
 static void _InitBeaconParameters(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
+	int error;
 
 	rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
 
@@ -601,11 +615,25 @@ static void _InitBeaconParameters(struct adapter *Adapter)
 	/*  beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
 	rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
 
-	haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL);
-	haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE);
-	haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
-	haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2);
-	haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1);
+	error = rtw_read8(Adapter, REG_BCN_CTRL, (u8 *) &haldata->RegBcnCtrlVal);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_TXPAUSE, &haldata->RegTxPause);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2, &haldata->RegFwHwTxQCtrl);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2, &haldata->RegReg542);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_CR + 1, &haldata->RegCR_1);
+	if (error)
+		return;
 }
 
 static void _BeaconFunctionEnable(struct adapter *Adapter,
@@ -665,14 +693,27 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt)
 {
 	u8 val8;
 	enum rt_rf_power_state rfpowerstate = rf_off;
+	int error;
 
 	if (adapt->pwrctrlpriv.bHWPowerdown) {
-		val8 = rtw_read8(adapt, REG_HSISR);
+		error = rtw_read8(adapt, REG_HSISR, &val8);
+		if (error)
+			return rfpowerstate;
+
 		DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8);
 		rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on;
 	} else { /*  rf on/off */
-		rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3)));
-		val8 = rtw_read8(adapt, REG_GPIO_IO_SEL);
+
+		error = rtw_read8(adapt, REG_MAC_PINMUX_CFG, &val8);
+		if (error)
+			return rfpowerstate;
+
+		rtw_write8(adapt, REG_MAC_PINMUX_CFG, val8 & ~(BIT(3)));
+
+		error = rtw_read8(adapt, REG_GPIO_IO_SEL, &val8);
+		if (error)
+			return rfpowerstate;
+
 		DBG_88E("GPIO_IN=%02x\n", val8);
 		rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
 	}
@@ -689,6 +730,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	struct pwrctrl_priv		*pwrctrlpriv = &Adapter->pwrctrlpriv;
 	struct registry_priv	*pregistrypriv = &Adapter->registrypriv;
 	u32 init_start_time = jiffies;
+	int error;
 
 	#define HAL_INIT_PROFILE_TAG(stage) do {} while (0)
 
@@ -835,7 +877,11 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 
 	/* Enable TX Report */
 	/* Enable Tx Report Timer */
-	value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+	error = rtw_read8(Adapter, REG_TX_RPT_CTRL, &value8);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
 	rtw_write8(Adapter,  REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0)));
 	/* Set MAX RPT MACID */
 	rtw_write8(Adapter,  REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
@@ -962,9 +1008,13 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 {
 	u8 val8;
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(Adapter);
+	int error;
 
 	/* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
-	val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+	error = rtw_read8(Adapter, REG_TX_RPT_CTRL, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1)));
 
 	/*  stop rx */
@@ -975,10 +1025,15 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 
 	/*  2. 0x1F[7:0] = 0		turn off RF */
 
-	val8 = rtw_read8(Adapter, REG_MCUFWDL);
-	if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
+	error = rtw_read8(Adapter, REG_MCUFWDL, &val8);
+	if (error) {
+		return;
+	} else if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
 		/*  Reset MCU 0x2[10]=0. */
-		val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1);
+		error = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1, &val8);
+		if (error)
+			return;
+
 		val8 &= ~BIT(2);	/*  0x2[10], FEN_CPUEN */
 		rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
 	}
@@ -988,26 +1043,43 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 
 	/* YJ,add,111212 */
 	/* Disable 32k */
-	val8 = rtw_read8(Adapter, REG_32K_CTRL);
+	error = rtw_read8(Adapter, REG_32K_CTRL, &val8);
+	if (error)
+		return;
 	rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0)));
 
 	/*  Card disable power action flow */
 	HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW);
 
 	/*  Reset MCU IO Wrapper */
-	val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+	error = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3))));
-	val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+	error = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+	if (error)
+		return;
 	rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3));
 
 	/* YJ,test add, 111207. For Power Consumption. */
-	val8 = rtw_read8(Adapter, GPIO_IN);
+	error = rtw_read8(Adapter, GPIO_IN, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, GPIO_OUT, val8);
 	rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
 
-	val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
+	error = rtw_read8(Adapter, REG_GPIO_IO_SEL, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
-	val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1);
+
+	error = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */
 	rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
 	haldata->bMacPwrCtrlOn = false;
@@ -1181,9 +1253,13 @@ static void _ReadPROMContent(
 {
 	struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(Adapter);
 	u8 eeValue;
+	int error;
 
 	/* check system boot selection */
-	eeValue = rtw_read8(Adapter, REG_9346CR);
+	error = rtw_read8(Adapter, REG_9346CR, &eeValue);
+	if (error)
+		return;
+
 	eeprom->EepromOrEfuse		= (eeValue & BOOT_FROM_EEPROM) ? true : false;
 	eeprom->bautoload_fail_flag	= (eeValue & EEPROM_EN) ? false : true;
 
@@ -1262,12 +1338,21 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
 {
 	u8 val8;
 	u8 mode = *((u8 *)val);
+	int error;
+
+	error = rtw_read8(Adapter, REG_BCN_CTRL, &val8);
+	if (error)
+		return;
 
 	/*  disable Port0 TSF update */
-	rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+	rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(4));
 
 	/*  set net_type */
-	val8 = rtw_read8(Adapter, MSR) & 0x0c;
+	error = rtw_read8(Adapter, MSR, &val8);
+	if (error)
+		return;
+
+	val8 &= 0x0c;
 	val8 |= mode;
 	rtw_write8(Adapter, MSR, val8);
 
@@ -1304,14 +1389,20 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
 		rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
 
 		/* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
-		rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+		error = rtw_read8(Adapter, REG_MBID_NUM, &val8);
+		if (error)
+			return;
+		rtw_write8(Adapter, REG_MBID_NUM, val8 | BIT(3) | BIT(4));
 
 		/* enable BCN0 Function for if1 */
 		/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
 		rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
 
 		/* dis BCN1 ATIM  WND if if2 is station */
-		rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+		error = rtw_read8(Adapter, REG_BCN_CTRL_1, &val8);
+		if (error)
+			return;
+		rtw_write8(Adapter, REG_BCN_CTRL_1, val8 | BIT(0));
 	}
 }
 
@@ -1345,8 +1436,16 @@ static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
 
 	if (*((u8 *)val))
 		rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
-	else
-		rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+	else {
+		u8 tmp;
+		int error;
+
+		error = rtw_read8(Adapter, bcn_ctrl_reg, &tmp);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, bcn_ctrl_reg, tmp & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+	}
 }
 
 static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1354,13 +1453,19 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	struct dm_priv	*pdmpriv = &haldata->dmpriv;
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+	int error;
+	u8 tmp;
 
 	switch (variable) {
 	case HW_VAR_MEDIA_STATUS:
 		{
 			u8 val8;
 
-			val8 = rtw_read8(Adapter, MSR) & 0x0c;
+			error = rtw_read8(Adapter, MSR, &val8);
+			if (error)
+				return;
+
+			val8 &= 0x0c;
 			val8 |= *((u8 *)val);
 			rtw_write8(Adapter, MSR, val8);
 		}
@@ -1369,7 +1474,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			u8 val8;
 
-			val8 = rtw_read8(Adapter, MSR) & 0x03;
+			error = rtw_read8(Adapter, MSR, &val8);
+			if (error)
+				return;
+
+			val8 &= 0x03;
 			val8 |= *((u8 *)val) << 2;
 			rtw_write8(Adapter, MSR, val8);
 		}
@@ -1407,7 +1516,12 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			/*  Set RRSR rate table. */
 			rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
 			rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
-			rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0);
+
+			error = rtw_read8(Adapter, REG_RRSR + 2, &tmp);
+			if (error)
+				return;
+
+			rtw_write8(Adapter, REG_RRSR + 2, tmp & 0xf0);
 
 			/*  Set RTS initial rate */
 			while (BrateCfg > 0x1) {
@@ -1437,13 +1551,21 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				StopTxBeacon(Adapter);
 
 			/* disable related TSF function */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3)));
+			error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+			if (error)
+				return;
+
+			rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(3)));
 
 			rtw_write32(Adapter, REG_TSFTR, tsf);
 			rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
 
 			/* enable related TSF function */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3));
+			error =  rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+			if (error)
+				return;
+
+			rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(3));
 
 			if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
 				ResumeTxBeacon(Adapter);
@@ -1471,35 +1593,48 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
 
 		/* disable update TSF */
-		rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+		error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
 		break;
 	case HW_VAR_MLME_SITESURVEY:
 		if (*((u8 *)val)) { /* under sitesurvey */
 			/* config RCR to receive different BSSID & not to receive data frame */
 			u32 v = rtw_read32(Adapter, REG_RCR);
+
 			v &= ~(RCR_CBSSID_BCN);
 			rtw_write32(Adapter, REG_RCR, v);
 			/* reject all data frame */
 			rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
 
 			/* disable update TSF */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+			error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+			if (error)
+				return;
+			rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
 		} else { /* sitesurvey done */
 			struct mlme_ext_priv	*pmlmeext = &Adapter->mlmeextpriv;
 			struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
 
+			error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+			if (error)
+				return;
+
 			if ((is_client_associated_to_ap(Adapter)) ||
 			    ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
 				/* enable to rx data frame */
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
 			} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
 			}
+
 			if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
 				rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
 			} else {
@@ -1517,6 +1652,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			u8 RetryLimit = 0x30;
 			u8 type = *((u8 *)val);
+			u8 tmp;
 			struct mlme_priv	*pmlmepriv = &Adapter->mlmepriv;
 
 			if (type == 0) { /*  prepare to join */
@@ -1541,7 +1677,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			} else if (type == 2) {
 				/* sta add event call back */
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+				if (error)
+					return;
+
+				rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
 
 				if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
 					RetryLimit = 0x7;
@@ -1671,7 +1811,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	case HW_VAR_ACM_CTRL:
 		{
 			u8 acm_ctrl = *((u8 *)val);
-			u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL);
+			u8 AcmCtrl;
+
+			error = rtw_read8(Adapter, REG_ACMHWCTRL, &AcmCtrl);
+			if (error)
+				return;
 
 			if (acm_ctrl > 1)
 				AcmCtrl = AcmCtrl | 0x1;
@@ -1699,6 +1843,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			u8 MinSpacingToSet;
 			u8 SecMinSpace;
+			u8 tmp;
 
 			MinSpacingToSet = *((u8 *)val);
 			if (MinSpacingToSet <= 7) {
@@ -1719,7 +1864,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				}
 				if (MinSpacingToSet < SecMinSpace)
 					MinSpacingToSet = SecMinSpace;
-				rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
+
+				error = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &tmp);
+				if (error)
+					return;
+
+				rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (tmp & 0xf8) |
+					  MinSpacingToSet);
 			}
 		}
 		break;
@@ -1868,7 +2019,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		break;
 	case HW_VAR_BCN_VALID:
 		/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
-		rtw_write8(Adapter, REG_TDECTRL + 2, rtw_read8(Adapter, REG_TDECTRL + 2) | BIT(0));
+		u8 tmp;
+
+		error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
 		break;
 	default:
 		break;
@@ -1880,17 +2037,23 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+	int error;
+	u8 tmp;
 
 	switch (variable) {
 	case HW_VAR_BASIC_RATE:
 		*((u16 *)(val)) = haldata->BasicRateSet;
 		fallthrough;
 	case HW_VAR_TXPAUSE:
-		val[0] = rtw_read8(Adapter, REG_TXPAUSE);
+		error = rtw_read8(Adapter, REG_TXPAUSE, val);
 		break;
 	case HW_VAR_BCN_VALID:
 		/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */
-		val[0] = (BIT(0) & rtw_read8(Adapter, REG_TDECTRL + 2)) ? true : false;
+		error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
+		if (error)
+			break;
+
+		val[0] = (BIT(0) & tmp) ? true : false;
 		break;
 	case HW_VAR_DM_FLAG:
 		val[0] = podmpriv->SupportAbility;
@@ -2035,6 +2198,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	u8 bResult = _SUCCESS;
+	int error;
 
 	switch (eVariable) {
 	case HAL_DEF_DBG_DM_FUNC:
@@ -2058,7 +2222,10 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
 			} else if (dm_func == 6) {/* turn on all dynamic func */
 				if (!(podmpriv->SupportAbility  & DYNAMIC_BB_DIG)) {
 					struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
-					pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50);
+
+					error = rtw_read8(Adapter, 0xc50, &pDigTable->CurIGValue);
+					if (error)
+						return _FAIL;
 				}
 				podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
 				DBG_88E("==> Turn on all dynamic function...\n");
@@ -2168,6 +2335,8 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 	struct mlme_ext_priv	*pmlmeext = &adapt->mlmeextpriv;
 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
 	u32 bcn_ctrl_reg			= REG_BCN_CTRL;
+	int error;
+	u8 tmp;
 	/* reset TSF, enable update TSF, correcting TSF On Beacon */
 
 	/* BCN interval */
@@ -2193,7 +2362,11 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 
 	ResumeTxBeacon(adapt);
 
-	rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1));
+	error = rtw_read8(adapt, bcn_ctrl_reg, &tmp);
+	if (error)
+		return;
+
+	rtw_write8(adapt, bcn_ctrl_reg, tmp | BIT(1));
 }
 
 static void rtl8188eu_init_default_value(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 953fa05dc30c..380d126c8b2f 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -101,26 +101,29 @@ static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata,
 	return status;
 }
 
-static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read8(struct intf_hdl *pintfhdl, u32 addr, u8 *data)
 {
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
-	u8 data = 0;
-
+	int res;
 
+	if (WARN_ON(unlikely(!data)))
+		return -EINVAL;
 
 	requesttype = 0x01;/* read_in */
 
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 1;
 
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
-
-
-
-	return data;
+	res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
+	if (res < 0)
+		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 8 bytes: %d\n", res);
+	else
+		/* Noone cares about positive return value */
+		res = 0;
 
+	return res;
 }
 
 static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 6b589413d56c..8e531d272927 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -60,7 +60,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext);
 
 /*  =========== EXtern Function Prototype */
 
-u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
 
 u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
 
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index f1b3074fa075..fd99b36abca6 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -85,7 +85,7 @@ struct intf_hdl;
 struct io_queue;
 
 struct _io_ops {
-	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
+	int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
 	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
 	u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
 	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
@@ -248,7 +248,7 @@ void unregister_intf_hdl(struct intf_hdl *pintfhdl);
 void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 
-u8 _rtw_read8(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
 u16 _rtw_read16(struct adapter *adapter, u32 addr);
 u32 _rtw_read32(struct adapter *adapter, u32 addr);
 void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
@@ -270,7 +270,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
 			     u8 *pmem, int timeout_ms);
 void _rtw_write_port_cancel(struct adapter *adapter);
 
-#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr))
+#define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
 #define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
 #define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
 #define rtw_read_mem(adapter, addr, cnt, mem)				\
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index ab4a9200f079..c9f0772bcbe1 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2074,6 +2074,7 @@ static int rtw_wx_read32(struct net_device *dev,
 	u32 data32;
 	u32 bytes;
 	u8 *ptmp;
+	int error;
 
 	padapter = (struct adapter *)rtw_netdev_priv(dev);
 	p = &wrqu->data;
@@ -2093,7 +2094,10 @@ static int rtw_wx_read32(struct net_device *dev,
 
 	switch (bytes) {
 	case 1:
-		data32 = rtw_read8(padapter, addr);
+		error = rtw_read8(padapter, addr, (u8 *) &data32);
+		if (error)
+			return error;
+
 		sprintf(extra, "0x%02X", data32);
 		break;
 	case 2:
@@ -2251,6 +2255,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 	u8 path;
 	u8 offset;
 	u32 value;
+	int error;
 
 	DBG_88E("%s\n", __func__);
 
@@ -2262,7 +2267,8 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 		RegRWStruct = (struct mp_rw_reg *)pdata;
 		switch (RegRWStruct->width) {
 		case 1:
-			RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
+			error = rtw_read8(padapter, RegRWStruct->offset,
+					 (u8 *) &RegRWStruct->value);
 			break;
 		case 2:
 			RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
@@ -3964,6 +3970,8 @@ static int rtw_dbg_port(struct net_device *dev,
 	struct security_priv *psecuritypriv = &padapter->securitypriv;
 	struct wlan_network *cur_network = &pmlmepriv->cur_network;
 	struct sta_priv *pstapriv = &padapter->stapriv;
+	int error;
+	u32 tmp;
 
 	pdata = (u32 *)&wrqu->data;
 
@@ -3978,7 +3986,8 @@ static int rtw_dbg_port(struct net_device *dev,
 	case 0x70:/* read_reg */
 		switch (minor_cmd) {
 		case 1:
-			DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+			if (!rtw_read8(padapter, arg, (u8 *) &tmp))
+				DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
 			break;
 		case 2:
 			DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
@@ -3992,7 +4001,9 @@ static int rtw_dbg_port(struct net_device *dev,
 		switch (minor_cmd) {
 		case 1:
 			rtw_write8(padapter, arg, extra_arg);
-			DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+			if (rtw_read8(padapter, arg, (u8 *) &tmp))
+				DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, (u8) tmp);
+
 			break;
 		case 2:
 			rtw_write16(padapter, arg, extra_arg);
@@ -4096,8 +4107,10 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read8(padapter, reg);
-			if (start_value + write_num - 1 == final)
+			error = rtw_read8(padapter, reg, &final);
+			if (error)
+				return error;
+			else if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
 			else
 				DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
@@ -4423,13 +4436,16 @@ static int rtw_dbg_port(struct net_device *dev,
 
 		case 0xfd:
 			rtw_write8(padapter, 0xc50, arg);
-			DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
+			DBG_88E_REG8("wr(0xc50) = 0x%x\n", padapter, 0xc50);
 			rtw_write8(padapter, 0xc58, arg);
-			DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+			error = rtw_read8(padapter, 0xc58, (u8 *) &tmp);
+			if (error)
+				return error;
+			DBG_88E("wr(0xc58) = 0x%x\n", (u8) tmp);
 			break;
 		case 0xfe:
-			DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
-			DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+			DBG_88E_REG8("rd(0xc50) = 0x%x\n", padapter, 0xc50);
+			DBG_88E_REG8("rd(0xc58) = 0x%x\n", padapter, 0xc58);
 			break;
 		case 0xff:
 			DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
@@ -5326,6 +5342,8 @@ static int rtw_mp_read_reg(struct net_device *dev,
 	char data[20], tmp[20];
 	u32 addr;
 	u32 ret, i = 0, j = 0, strtout = 0;
+	u32 val32;
+	int error;
 
 	if (!input)
 		return -ENOMEM;
@@ -5361,7 +5379,10 @@ static int rtw_mp_read_reg(struct net_device *dev,
 	switch (width) {
 	case 'b':
 		/*  1 byte */
-		sprintf(extra, "%d\n",  rtw_read8(padapter, addr));
+		error = rtw_read8(padapter, addr, (u8 *) &val32);
+		if (error)
+			return error;
+		sprintf(extra, "%d\n", (u8) val32);
 		wrqu->length = strlen(extra);
 		break;
 	case 'w':
@@ -5889,6 +5910,8 @@ static int rtw_mp_arx(struct net_device *dev,
 	u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0;
 	char	*input = kmalloc(wrqu->length, GFP_KERNEL);
 	struct adapter *padapter = rtw_netdev_priv(dev);
+	int error = 0;
+	u8 tmp;
 
 	if (!input)
 		return -ENOMEM;
@@ -5934,13 +5957,25 @@ static int rtw_mp_arx(struct net_device *dev,
 		OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF);
 		OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000);
 		OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF);
-		CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c));
+
+		error = rtw_read8(padapter, 0xa5b, &tmp);
+		if (error)
+			goto end;
+
+		CCK_FA = tmp << 8;
+
+		error = rtw_read8(padapter, 0xa5c, &tmp);
+		if (error)
+			goto end;
+
+		CCK_FA |= tmp;
 
 		sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA);
 	}
 	wrqu->length = strlen(extra) + 1;
+end:
 	kfree(input);
-	return 0;
+	return error;
 }
 
 static int rtw_mp_trx_query(struct net_device *dev,
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC v2 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
                                   ` (2 preceding siblings ...)
  2021-08-22 14:35                 ` [PATCH RFC v2 3/6] staging: r8188eu: add error handling of rtw_read8 Pavel Skripkin
@ 2021-08-22 14:35                 ` Pavel Skripkin
  2021-08-22 14:36                 ` [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32 Pavel Skripkin
                                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 14:35 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

_rtw_read16 function can fail in case of usb transfer failure. But
previous function prototype wasn't designed to return an error to
caller. It can cause a lot uninit value bugs all across the driver code,
since rtw_read16() returns local stack variable to caller.

Fix it by changing the prototype of this function. Now it returns an
int: 0 on success, negative error value on failure and callers should pass
the pointer to storage location for register value.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_debug.c      |  7 +++-
 drivers/staging/r8188eu/core/rtw_io.c         |  9 ++---
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  4 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |  4 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 29 +++++++++++----
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  5 ++-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 37 ++++++++++++++++---
 drivers/staging/r8188eu/hal/usb_ops_linux.c   | 19 ++++++++--
 .../staging/r8188eu/include/odm_interface.h   |  2 +-
 drivers/staging/r8188eu/include/rtw_io.h      |  6 +--
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 28 +++++++++++---
 11 files changed, 112 insertions(+), 38 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 8b7d3eb12bd0..a41675e101ac 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -91,7 +91,12 @@ int proc_get_read_reg(char *page, char **start,
 				proc_get_read_addr, (u8) tmp);
 		break;
 	case 2:
-		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
+		error = rtw_read16(padapter, proc_get_read_addr, (u16 *) &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n",
+				proc_get_read_addr, (u16) tmp);
 		break;
 	case 4:
 		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index 2714506c8ffb..fd64893c778d 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -45,18 +45,15 @@ int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
 	return _read8(pintfhdl, addr, data);
 }
 
-u16 _rtw_read16(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
 {
-	u16 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
-	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+	int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
 
 	_read16 = pintfhdl->io_ops._read16;
 
-	r_val = _read16(pintfhdl, addr);
-
-	return r_val;
+	return _read16(pintfhdl, addr, data);
 }
 
 u32 _rtw_read32(struct adapter *adapter, u32 addr)
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index 894ab456f202..c6f7636c2174 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -653,7 +653,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 			status = NDIS_STATUS_NOT_ACCEPTED;
 		break;
 	case 2:
-		RegRWStruct->value = rtw_read16(Adapter, offset);
+		error = rtw_read16(Adapter, offset, (u16 *) &RegRWStruct->value);
+		if (error)
+			status = NDIS_STATUS_NOT_ACCEPTED;
 		break;
 	default:
 		width = 4;
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 9a9df98da727..669d3e5eafb6 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -10,10 +10,10 @@ int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data)
 	return rtw_read8(Adapter, RegAddr, data);
 }
 
-u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read16(Adapter, RegAddr);
+	return rtw_read16(Adapter, RegAddr, data);
 }
 
 u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index cfc429965b7d..94e2828c328e 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -262,7 +262,11 @@ static void efuse_read_phymap_from_txpktbuf(
 			 * do not remove it as the rtw_read16() call consumes
 			 * 2 bytes from the EEPROM source.
 			 */
-			u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
+			u16 lenc;
+
+			error = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &lenc);
+			if (error)
+				return;
 
 			len = le32_to_cpu(lo32) & 0x0000ffff;
 
@@ -778,21 +782,27 @@ hal_EfusePowerSwitch_RTL8188E(
 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
 
 		/*  1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
-		tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
-		if (!(tmpV16 & PWC_EV12V)) {
+		error = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
+		if (error) {
+			return;
+		} else if (!(tmpV16 & PWC_EV12V)) {
 			tmpV16 |= PWC_EV12V;
 			rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
 		}
 		/*  Reset: 0x0000h[28], default valid */
-		tmpV16 =  rtw_read16(pAdapter, REG_SYS_FUNC_EN);
-		if (!(tmpV16 & FEN_ELDR)) {
+		error = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
+		if (error) {
+			return;
+		} else if (!(tmpV16 & FEN_ELDR)) {
 			tmpV16 |= FEN_ELDR;
 			rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
 		}
 
 		/*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
-		tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
-		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
+		error = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
+		if (error) {
+			return;
+		} else if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
 			tmpV16 |= (LOADER_CLK_EN | ANA8M);
 			rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
 		}
@@ -1915,8 +1925,11 @@ u8 GetEEPROMSize8188E(struct adapter *padapter)
 {
 	u8 size = 0;
 	u32	cr;
+	int error;
 
-	cr = rtw_read16(padapter, REG_9346CR);
+	error = rtw_read16(padapter, REG_9346CR, (u16 *) &cr);
+	if (error)
+		return size;
 	/*  6: EEPROM used is 93C46, 4: boot from E-Fuse. */
 	size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
 
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index f6d4c91a97a2..3afb66195413 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -577,11 +577,14 @@ PHY_BBConfig8188E(
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(Adapter);
 	u32 RegVal;
 	u8 CrystalCap;
+	int error;
 
 	phy_InitBBRFRegisterDefinition(Adapter);
 
 	/*  Enable BB and RF */
-	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+	error = rtw_read16(Adapter, REG_SYS_FUNC_EN, (u16 *) &RegVal);
+	if (error)
+		return _FAIL;
 	rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
 
 	/*  20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 4f1d7f9b43c3..4ecccc6499aa 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -90,6 +90,8 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
 	u16 value16;
 	/*  HW Power on sequence */
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(adapt);
+	int error;
+
 	if (haldata->bMacPwrCtrlOn)
 		return _SUCCESS;
 
@@ -103,7 +105,10 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
 	rtw_write16(adapt, REG_CR, 0x00);  /* suggseted by zhouzhou, by page, 20111230 */
 
 		/*  Enable MAC DMA/WMAC/SCHEDULE/SEC block */
-	value16 = rtw_read16(adapt, REG_CR);
+	error = rtw_read16(adapt, REG_CR, &value16);
+	if (error)
+		return _FAIL;
+
 	value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
 				| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
 	/*  for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
@@ -207,7 +212,14 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
 				       u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
 				       u16 hiQ)
 {
-	u16 value16	= (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+	u16 value16;
+	int error;
+
+	error = rtw_read16(Adapter, REG_TRXDMA_CTRL, &value16);
+	if (error)
+		return;
+
+	value16 &= 0x7;
 
 	value16 |= _TXDMA_BEQ_MAP(beQ)	| _TXDMA_BKQ_MAP(bkQ) |
 		   _TXDMA_VIQ_MAP(viQ)	| _TXDMA_VOQ_MAP(voQ) |
@@ -868,7 +880,12 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	/*  Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
 	/*  */
 	/*  Enable MACTXEN/MACRXEN block */
-	value16 = rtw_read16(Adapter, REG_CR);
+	error = rtw_read16(Adapter, REG_CR, &value16);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
+
 	value16 |= (MACTXEN | MACRXEN);
 	rtw_write8(Adapter, REG_CR, value16);
 
@@ -937,6 +954,8 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 		Adapter->mppriv.channel = haldata->CurrentChannel;
 		MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel);
 	} else {
+		u16 val16;
+
 		/*  2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
 		/*  and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
 		/*  call initstruct adapter. May cause some problem?? */
@@ -956,7 +975,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 		rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
 
 		/* enable tx DMA to drop the redundate data of packet */
-		rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+		error = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &val16);
+		if (error) {
+			status = _FAIL;
+			goto exit;
+		}
+
+		rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (val16 | DROP_DATA_EN));
 
 		HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
 		/*  2010/08/26 MH Merge from 8192CE. */
@@ -1982,7 +2007,9 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			rtw_write8(Adapter, REG_TXPAUSE, 0xff);
 
 			/* keep sn */
-			Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
+			error = rtw_read16(Adapter, REG_NQOS_SEQ, &Adapter->xmitpriv.nqos_ssn);
+			if (error)
+				return;
 
 			if (!pwrpriv->bkeepfwalive) {
 				/* RX DMA stop */
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 380d126c8b2f..58e852555f54 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -126,19 +126,30 @@ static int usb_read8(struct intf_hdl *pintfhdl, u32 addr, u8 *data)
 	return res;
 }
 
-static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
 {
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
-	__le32 data;
+	int res;
+	__le32 tmp;
+
+	if (WARN_ON(unlikely(!data)))
+		return -EINVAL;
 
 	requesttype = 0x01;/* read_in */
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 2;
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
+	if (res < 0) {
+		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 16 bytes: %d\n", res);
+	} else {
+		/* Noone cares about positive return value */
+		*data = le32_to_cpu(tmp) & 0xffff;
+		res = 0;
+	}
 
-	return (u16)(le32_to_cpu(data) & 0xffff);
+	return res;
 }
 
 static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 8e531d272927..2455dae6eebb 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -62,7 +62,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext);
 
 int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
 
-u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data);
 
 u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
 
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index fd99b36abca6..c44554c848cf 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -86,7 +86,7 @@ struct io_queue;
 
 struct _io_ops {
 	int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
-	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+	int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
 	u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
 	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
 	int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
@@ -249,7 +249,7 @@ void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 
 int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
-u16 _rtw_read16(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
 u32 _rtw_read32(struct adapter *adapter, u32 addr);
 void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
@@ -271,7 +271,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
 void _rtw_write_port_cancel(struct adapter *adapter);
 
 #define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
-#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
+#define rtw_read16(adapter, addr, data) _rtw_read16((adapter), (addr), (data))
 #define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
 #define rtw_read_mem(adapter, addr, cnt, mem)				\
 	_rtw_read_mem((adapter), (addr), (cnt), (mem))
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index c9f0772bcbe1..79f0fbaa841e 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2101,7 +2101,10 @@ static int rtw_wx_read32(struct net_device *dev,
 		sprintf(extra, "0x%02X", data32);
 		break;
 	case 2:
-		data32 = rtw_read16(padapter, addr);
+		error = rtw_read16(padapter, addr, (u16 *) &data32);
+		if (error)
+			return error;
+
 		sprintf(extra, "0x%04X", data32);
 		break;
 	case 4:
@@ -2271,7 +2274,8 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 					 (u8 *) &RegRWStruct->value);
 			break;
 		case 2:
-			RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
+			error = rtw_read16(padapter, RegRWStruct->offset,
+					  (u16 *) &RegRWStruct->value);
 			break;
 		case 4:
 			RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
@@ -3990,7 +3994,8 @@ static int rtw_dbg_port(struct net_device *dev,
 				DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
 			break;
 		case 2:
-			DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+			if (!rtw_read16(padapter, arg, (u16 *) &tmp))
+				DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
 			break;
 		case 4:
 			DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
@@ -4006,8 +4011,12 @@ static int rtw_dbg_port(struct net_device *dev,
 
 			break;
 		case 2:
+			error = rtw_read16(padapter, arg, (u16 *) &tmp);
+			if (error)
+				return error;
+
 			rtw_write16(padapter, arg, extra_arg);
-			DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+			DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, (u16) tmp);
 			break;
 		case 4:
 			rtw_write32(padapter, arg, extra_arg);
@@ -4138,7 +4147,10 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read16(padapter, reg);
+			error = rtw_read16(padapter, reg, &final);
+			if (error)
+				return error;
+
 			if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
 			else
@@ -5387,7 +5399,11 @@ static int rtw_mp_read_reg(struct net_device *dev,
 		break;
 	case 'w':
 		/*  2 bytes */
-		sprintf(data, "%04x\n", rtw_read16(padapter, addr));
+		error = rtw_read16(padapter, addr, (u16 *) &val32);
+		if (error)
+			return error;
+
+		sprintf(data, "%04x\n", (u16) val32);
 		for (i = 0; i <= strlen(data); i++) {
 			if (i % 2 == 0) {
 				tmp[j] = ' ';
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
                                   ` (3 preceding siblings ...)
  2021-08-22 14:35                 ` [PATCH RFC v2 4/6] staging: r8188eu: add error handling of rtw_read16 Pavel Skripkin
@ 2021-08-22 14:36                 ` Pavel Skripkin
  2021-08-23 23:33                   ` Phillip Potter
  2021-08-24  6:58                   ` [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32 Dan Carpenter
  2021-08-22 14:36                 ` [PATCH RFC v2 6/6] staging: r8188eu: make ReadEFuse return an int Pavel Skripkin
                                   ` (3 subsequent siblings)
  8 siblings, 2 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 14:36 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

_rtw_read32 function can fail in case of usb transfer failure. But
previous function prototype wasn't designed to return an error to
caller. It can cause a lot uninit value bugs all across the driver code,
since rtw_read32() returns local stack variable to caller.

Fix it by changing the prototype of this function. Now it returns an
int: 0 on success, negative error value on failure and callers should pass
the pointer to storage location for register value.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_debug.c      |  61 +++++++--
 drivers/staging/r8188eu/core/rtw_efuse.c      |  14 ++-
 drivers/staging/r8188eu/core/rtw_io.c         |   9 +-
 drivers/staging/r8188eu/core/rtw_mp.c         |  18 ++-
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |   4 +-
 drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   5 +-
 drivers/staging/r8188eu/core/rtw_sreset.c     |   9 +-
 .../r8188eu/hal/Hal8188ERateAdaptive.c        |   8 +-
 drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |   2 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |   4 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   |  63 ++++++++--
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  12 +-
 drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  14 ++-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 119 +++++++++++++++---
 drivers/staging/r8188eu/hal/usb_ops_linux.c   |  19 ++-
 .../staging/r8188eu/include/odm_interface.h   |   2 +-
 drivers/staging/r8188eu/include/rtw_io.h      |   6 +-
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  |  90 ++++++++-----
 18 files changed, 354 insertions(+), 105 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index a41675e101ac..c76feb44ecfa 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -99,7 +99,12 @@ int proc_get_read_reg(char *page, char **start,
 				proc_get_read_addr, (u16) tmp);
 		break;
 	case 4:
-		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
+		error = rtw_read32(padapter, proc_get_read_addr, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n",
+				proc_get_read_addr, tmp);
 		break;
 	default:
 		len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
@@ -315,13 +320,20 @@ int proc_get_mac_reg_dump1(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 
 	for (i = 0x0; i < 0x300; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -338,13 +350,20 @@ int proc_get_mac_reg_dump2(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 	memset(page, 0, count);
 	for (i = 0x300; i < 0x600; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -361,13 +380,20 @@ int proc_get_mac_reg_dump3(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 
 	for (i = 0x600; i < 0x800; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return error;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -384,12 +410,19 @@ int proc_get_bb_reg_dump1(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0x800; i < 0xB00; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -405,12 +438,19 @@ int proc_get_bb_reg_dump2(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0xB00; i < 0xE00; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -426,12 +466,19 @@ int proc_get_bb_reg_dump3(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0xE00; i < 0x1000; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index b471f6446f78..dfe60bc6a547 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -183,9 +183,15 @@ ReadEFuseByte(
 
 	/* Check bit 32 read-ready */
 	retry = 0;
-	value32 = rtw_read32(Adapter, EFUSE_CTRL);
+	error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+	if (error)
+		return;
+
 	while (!(((value32 >> 24) & 0xff) & 0x80)  && (retry < 10000)) {
-		value32 = rtw_read32(Adapter, EFUSE_CTRL);
+		error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+		if (error)
+			return;
+
 		retry++;
 	}
 
@@ -194,7 +200,9 @@ ReadEFuseByte(
 	/*  Designer says that there shall be some delay after ready bit is set, or the */
 	/*  result will always stay on last data we read. */
 	udelay(50);
-	value32 = rtw_read32(Adapter, EFUSE_CTRL);
+	error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+	if (error)
+		return;
 
 	*pbuf = (u8)(value32 & 0xff);
 }
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index fd64893c778d..df4d8ac8aadc 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -56,18 +56,15 @@ int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
 	return _read16(pintfhdl, addr, data);
 }
 
-u32 _rtw_read32(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read32(struct adapter *adapter, u32 addr, u32 *data)
 {
-	u32 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
-	u32	(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+	int	(*_read32)(struct intf_hdl *pintfhdl, u32 addr, u32 *data);
 
 	_read32 = pintfhdl->io_ops._read32;
 
-	r_val = _read32(pintfhdl, addr);
-
-	return r_val;
+	return _read32(pintfhdl, addr, data);
 }
 
 int _rtw_write8(struct adapter *adapter, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 76f0bc399819..e990e81966af 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -765,12 +765,17 @@ static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
 {
 	/* selection */
 	u32 phyrx_set = 0, count = 0;
+	int error;
 
 	phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
 	rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
 
 	/* Read packet count */
-	count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
+	error = rtw_read32(pAdapter, REG_RXERR_RPT, &count);
+	if (error)
+		return count;
+
+	count &= RXERR_COUNTER_MASK;
 
 	return count;
 }
@@ -803,8 +808,12 @@ u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
 static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
 {
 	int psd_val;
+	int error;
+
+	error = rtw_read32(pAdapter, 0x808, &psd_val);
+	if (error)
+		return 0;
 
-	psd_val = rtw_read32(pAdapter, 0x808);
 	psd_val &= 0xFFBFFC00;
 	psd_val |= point;
 
@@ -814,7 +823,10 @@ static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
 
 	rtw_write32(pAdapter, 0x808, psd_val);
 	mdelay(1);
-	psd_val = rtw_read32(pAdapter, 0x8B4);
+
+	error = rtw_read32(pAdapter, 0x8B4, &psd_val);
+	if (error)
+		return 0;
 
 	psd_val &= 0x0000FFFF;
 
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c6f7636c2174..9eaef9c73516 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -659,7 +659,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 		break;
 	default:
 		width = 4;
-		RegRWStruct->value = rtw_read32(Adapter, offset);
+		error = rtw_read32(Adapter, offset, &RegRWStruct->value);
+		if (error)
+			status = NDIS_STATUS_NOT_ACCEPTED;
 		break;
 	}
 
diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
index c3897b29121c..4335907acbc3 100644
--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
@@ -55,6 +55,7 @@ int ips_leave(struct adapter *padapter)
 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	int result = _SUCCESS;
 	int keyid;
+	u32 tmp;
 
 	_enter_pwrlock(&pwrpriv->lock);
 
@@ -83,7 +84,9 @@ int ips_leave(struct adapter *padapter)
 			}
 		}
 
-		DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
+		if (!rtw_read32(padapter, 0x4c, &tmp))
+			DBG_88E("==> ips_leave.....LED(0x%08x)...\n", tmp);
+
 		pwrpriv->bips_processing = false;
 
 		pwrpriv->bkeepfwalive = false;
diff --git a/drivers/staging/r8188eu/core/rtw_sreset.c b/drivers/staging/r8188eu/core/rtw_sreset.c
index 8e1bc62e74e5..ec5d070e1641 100644
--- a/drivers/staging/r8188eu/core/rtw_sreset.c
+++ b/drivers/staging/r8188eu/core/rtw_sreset.c
@@ -29,13 +29,18 @@ u8 sreset_get_wifi_status(struct adapter *padapter)
 {
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+	int error;
 	u8 status = WIFI_STATUS_SUCCESS;
 	u32 val32 = 0;
 
 	if (psrtpriv->silent_reset_inprogress)
 		return status;
-	val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
+	error = rtw_read32(padapter, REG_TXDMA_STATUS, &val32);
+	if (error) {
+		psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
+		return WIFI_MAC_TXDMA_ERROR;
+	}
+
 	if (val32 == 0xeaeaeaea) {
 		psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
 	} else if (val32 != 0) {
diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
index d873672feb27..bd4580eba0a9 100644
--- a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
+++ b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
@@ -316,19 +316,19 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0000000d;
 		break;
 	case 12:
-		MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR0);
+		ODM_Read4Byte(dm_odm, REG_ARFR0, &MaskFromReg);
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
 		break;
 	case 13:
-		MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR1);
+		ODM_Read4Byte(dm_odm, REG_ARFR1, &MaskFromReg);
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
 		break;
 	case 14:
-		MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR2);
+		ODM_Read4Byte(dm_odm, REG_ARFR2, &MaskFromReg);
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
 		break;
 	case 15:
-		MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR3);
+		ODM_Read4Byte(dm_odm, REG_ARFR3, &MaskFromReg);
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
 		break;
 	default:
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index 3545ad60dc00..725a18dc3979 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -667,7 +667,7 @@ static void _PHY_SaveMACRegisters(
 		if (error)
 			return;
 	}
-	MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
+	ODM_Read4Byte(dm_odm, MACReg[i], MACBackup + i);
 }
 
 static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 669d3e5eafb6..a47319dec231 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -16,10 +16,10 @@ int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data)
 	return rtw_read16(Adapter, RegAddr, data);
 }
 
-u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 *data)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read32(Adapter, RegAddr);
+	return rtw_read32(Adapter, RegAddr, data);
 }
 
 void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 94e2828c328e..69649a381727 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -254,8 +254,16 @@ static void efuse_read_phymap_from_txpktbuf(
 
 
 		/* data from EEPROM needs to be in LE */
-		lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
-		hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));
+		error = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &lo32);
+		if (error)
+			return;
+		lo32 = cpu_to_le32(lo32);
+
+
+		error = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &hi32);
+		if (error)
+			return;
+		hi32 = cpu_to_le32(hi32);
 
 		if (i == 0) {
 			/* Although lenc is only used in a debug statement,
@@ -375,6 +383,8 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 	u32 addr, rstatus, loop = 0;
 	u16 data_cnts = (data_len / 8) + 1;
 	u8 *pbuf = vzalloc(data_len + 10);
+	int error;
+
 	DBG_88E("###### %s ######\n", __func__);
 
 	rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
@@ -384,12 +394,25 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 			rtw_usleep_os(2);
 			loop = 0;
 			do {
-				rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24));
+				error = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL, &reg_140);
+				if (error)
+					return;
+
+				reg_140 &= BIT(24);
+				rstatus = reg_140;
 				if (rstatus) {
-					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
+					error = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L,
+							  &fifo_data);
+					if (error)
+						return;
+
 					memcpy(pbuf + (addr * 8), &fifo_data, 4);
 
-					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
+					error = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H,
+							  &fifo_data);
+					if (error)
+						return;
+
 					memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
 				}
 				rtw_usleep_os(2);
@@ -557,10 +580,14 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 {
 	u32	counter = 0;
 	u32	value32;
+	int error;
 
 	/*  polling CheckSum report */
 	do {
-		value32 = rtw_read32(padapter, REG_MCUFWDL);
+		error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+		if (error)
+			return _FAIL;
+
 		if (value32 & FWDL_ChkSum_rpt)
 			break;
 	} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -571,7 +598,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 	}
 	DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
 
-	value32 = rtw_read32(padapter, REG_MCUFWDL);
+	error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+	if (error)
+		return _FAIL;
+
 	value32 |= MCUFWDL_RDY;
 	value32 &= ~WINTINI_RDY;
 	rtw_write32(padapter, REG_MCUFWDL, value32);
@@ -581,8 +611,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 	/*  polling for FW ready */
 	counter = 0;
 	do {
-		value32 = rtw_read32(padapter, REG_MCUFWDL);
-		if (value32 & WINTINI_RDY) {
+		error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+		if (error) {
+			return _FAIL;
+		} else if (value32 & WINTINI_RDY) {
 			DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
 			return _SUCCESS;
 		}
@@ -1765,12 +1797,16 @@ static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8
 static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
 {
 	u32				value32;
-	struct HAL_VERSION		ChipVersion;
+	struct HAL_VERSION		ChipVersion = {};
 	struct hal_data_8188e	*pHalData;
+	int error;
 
 	pHalData = GET_HAL_DATA(padapter);
 
-	value32 = rtw_read32(padapter, REG_SYS_CFG);
+	error = rtw_read32(padapter, REG_SYS_CFG, &value32);
+	if (error)
+		return ChipVersion;
+
 	ChipVersion.ICType = CHIP_8188E;
 	ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
 
@@ -1949,12 +1985,15 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
 	s32	count = 0;
 	u32	value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
 	u16	LLTReg = REG_LLT_INIT;
+	int error;
 
 	rtw_write32(padapter, LLTReg, value);
 
 	/* polling */
 	do {
-		value = rtw_read32(padapter, LLTReg);
+		error = rtw_read32(padapter, LLTReg, &value);
+		if (error)
+			return _FAIL;
 		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
 			break;
 
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 3afb66195413..24b2afb62d68 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -75,8 +75,12 @@ rtl8188e_PHY_QueryBBReg(
 	)
 {
 	u32 ReturnValue = 0, OriginalValue, BitShift;
+	int error;
+
+	error = rtw_read32(Adapter, RegAddr, &OriginalValue);
+	if (error)
+		return ReturnValue;
 
-	OriginalValue = rtw_read32(Adapter, RegAddr);
 	BitShift = phy_CalculateBitShift(BitMask);
 	ReturnValue = (OriginalValue & BitMask) >> BitShift;
 	return ReturnValue;
@@ -103,9 +107,13 @@ rtl8188e_PHY_QueryBBReg(
 void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
 {
 	u32 OriginalValue, BitShift;
+	int error;
 
 	if (BitMask != bMaskDWord) { /* if not "double word" write */
-		OriginalValue = rtw_read32(Adapter, RegAddr);
+		error = rtw_read32(Adapter, RegAddr, &OriginalValue);
+		if (error)
+			return;
+
 		BitShift = phy_CalculateBitShift(BitMask);
 		Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
 	}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 39dacfb23570..a023a0669ffd 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -14,14 +14,16 @@ void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
 {
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+	int error;
 	unsigned long current_time;
 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
 	unsigned int diff_time;
 	u32 txdma_status;
 
-	txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
-	if (txdma_status != 0x00) {
+	error = rtw_read32(padapter, REG_TXDMA_STATUS, &txdma_status);
+	if (error) {
+		return;
+	} else if (txdma_status != 0x00) {
 		DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
 		rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
 		rtl8188e_silentreset_for_specific_platform(padapter);
@@ -51,8 +53,10 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
 	u8 fw_status = 0;
 	int error;
 
-	rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
-	if (rx_dma_status != 0x00) {
+	error = rtw_read32(padapter, REG_RXDMA_STATUS, &rx_dma_status);
+	if (error) {
+		return;
+	} else if (rx_dma_status != 0x00) {
 		DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
 		rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
 	}
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 4ecccc6499aa..3826476e3396 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -338,8 +338,12 @@ static void _InitQueuePriority(struct adapter *Adapter)
 static void _InitNetworkType(struct adapter *Adapter)
 {
 	u32 value32;
+	int error;
+
+	error = rtw_read32(Adapter, REG_CR, &value32);
+	if (error)
+		return;
 
-	value32 = rtw_read32(Adapter, REG_CR);
 	/*  TODO: use the other function to set network type */
 	value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
 
@@ -381,9 +385,13 @@ static void _InitAdaptiveCtrl(struct adapter *Adapter)
 {
 	u16 value16;
 	u32 value32;
+	int error;
 
 	/*  Response Rate Set */
-	value32 = rtw_read32(Adapter, REG_RRSR);
+	error = rtw_read32(Adapter, REG_RRSR, &value32);
+	if (error)
+		return;
+
 	value32 &= ~RATE_BITMAP_ALL;
 	value32 |= RATE_RRSR_CCK_ONLY_1M;
 	rtw_write32(Adapter, REG_RRSR, value32);
@@ -482,12 +490,16 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	u32 value32;
+	int error;
 
 	if (Adapter->registrypriv.wifi_spec)
 		haldata->UsbTxAggMode = false;
 
 	if (haldata->UsbTxAggMode) {
-		value32 = rtw_read32(Adapter, REG_TDECTRL);
+		error = rtw_read32(Adapter, REG_TDECTRL, &value32);
+		if (error)
+			return;
+
 		value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
 		value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
 
@@ -671,12 +683,18 @@ enum {
 static void _InitAntenna_Selection(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(Adapter);
+	u32 val32;
+	int error;
 
 	if (haldata->AntDivCfg == 0)
 		return;
 	DBG_88E("==>  %s ....\n", __func__);
 
-	rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23));
+	error = rtw_read32(Adapter, REG_LEDCFG0, &val32);
+	if (error)
+		return;
+
+	rtw_write32(Adapter, REG_LEDCFG0, val32 | BIT(23));
 	PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
 
 	if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
@@ -737,7 +755,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	u8 value8 = 0;
 	u16  value16;
 	u8 txpktbuf_bndy;
-	u32 status = _SUCCESS;
+	u32 status = _SUCCESS, val32;
 	struct hal_data_8188e		*haldata = GET_HAL_DATA(Adapter);
 	struct pwrctrl_priv		*pwrctrlpriv = &Adapter->pwrctrlpriv;
 	struct registry_priv	*pregistrypriv = &Adapter->registrypriv;
@@ -1007,7 +1025,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	rtw_write8(Adapter, REG_USB_HRPWM, 0);
 
 	/* ack for xmit mgmt frames. */
-	rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
+	error = rtw_read32(Adapter, REG_FWHW_TXQ_CTRL, &val32);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
+
+	rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, val32 | BIT(12));
 
 exit:
 	HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
@@ -1480,6 +1504,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
 	int error;
 	u8 tmp;
+	u32 val32;
 
 	switch (variable) {
 	case HW_VAR_MEDIA_STATUS:
@@ -1598,11 +1623,17 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		break;
 	case HW_VAR_CHECK_BSSID:
 		if (*((u8 *)val)) {
-			rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+			error = rtw_read32(Adapter, REG_RCR, &val32);
+			if (error)
+				return;
+
+			rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 		} else {
 			u32 val32;
 
-			val32 = rtw_read32(Adapter, REG_RCR);
+			error = rtw_read32(Adapter, REG_RCR, &val32);
+			if (error)
+				return;
 
 			val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 
@@ -1627,7 +1658,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	case HW_VAR_MLME_SITESURVEY:
 		if (*((u8 *)val)) { /* under sitesurvey */
 			/* config RCR to receive different BSSID & not to receive data frame */
-			u32 v = rtw_read32(Adapter, REG_RCR);
+			u32 v;
+
+			error = rtw_read32(Adapter, REG_RCR, &v);
+			if (error)
+				return;
 
 			v &= ~(RCR_CBSSID_BCN);
 			rtw_write32(Adapter, REG_RCR, v);
@@ -1661,14 +1696,27 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			}
 
 			if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
-				rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+				error = rtw_read32(Adapter, REG_RCR, &val32);
+				if (error)
+					return;
+
+				rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_BCN);
 			} else {
+				u32 v;
+
 				if (Adapter->in_cta_test) {
-					u32 v = rtw_read32(Adapter, REG_RCR);
+					error = rtw_read32(Adapter, REG_RCR, &v);
+					if (error)
+						return;
+
 					v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 					rtw_write32(Adapter, REG_RCR, v);
 				} else {
-					rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+					error = rtw_read32(Adapter, REG_RCR, &v);
+					if (error)
+						return;
+
+					rtw_write32(Adapter, REG_RCR, v | RCR_CBSSID_BCN);
 				}
 			}
 		}
@@ -1679,17 +1727,26 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			u8 type = *((u8 *)val);
 			u8 tmp;
 			struct mlme_priv	*pmlmepriv = &Adapter->mlmepriv;
+			u32 v;
 
 			if (type == 0) { /*  prepare to join */
 				/* enable to rx data frame.Accept all data frame */
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 
 				if (Adapter->in_cta_test) {
-					u32 v = rtw_read32(Adapter, REG_RCR);
+					error = rtw_read32(Adapter, REG_RCR, &v);
+					if (error)
+						return;
+
 					v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 					rtw_write32(Adapter, REG_RCR, v);
 				} else {
-					rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+					error = rtw_read32(Adapter, REG_RCR, &v);
+					if (error)
+						return;
+
+					rtw_write32(Adapter, REG_RCR,
+						    v | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 				}
 
 				if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
@@ -2002,6 +2059,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
 			u8 trycnt = 100;
+			u32 v;
 
 			/* pause tx */
 			rtw_write8(Adapter, REG_TXPAUSE, 0xff);
@@ -2013,9 +2071,18 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 
 			if (!pwrpriv->bkeepfwalive) {
 				/* RX DMA stop */
-				rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+
+				error = rtw_read32(Adapter, REG_RXPKT_NUM, &v);
+				if (error)
+					return;
+
+				rtw_write32(Adapter, REG_RXPKT_NUM, (v | RW_RELEASE_EN));
 				do {
-					if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
+					error = rtw_read32(Adapter, REG_RXPKT_NUM, &v);
+					if (error)
+						return;
+
+					if (!(v & RXDMA_IDLE))
 						break;
 				} while (trycnt--);
 				if (trycnt == 0)
@@ -2066,6 +2133,7 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
 	int error;
 	u8 tmp;
+	u32 val32;
 
 	switch (variable) {
 	case HW_VAR_BASIC_RATE:
@@ -2097,7 +2165,13 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				val[0] = true;
 			} else {
 				u32 valRCR;
-				valRCR = rtw_read32(Adapter, REG_RCR);
+
+				error = rtw_read32(Adapter, REG_RCR, &valRCR);
+				if (error) {
+					*val = false;
+					return;
+				}
+
 				valRCR &= 0x00070000;
 				if (valRCR)
 					val[0] = false;
@@ -2116,7 +2190,11 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		*val = haldata->bMacPwrCtrlOn;
 		break;
 	case HW_VAR_CHK_HI_QUEUE_EMPTY:
-		*val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false;
+		error = rtw_read32(Adapter, REG_HGQ_INFORMATION, &val32);
+		if (error || val32 & 0x0000ff00)
+			*val = false;
+		else
+			*val = true;
 		break;
 	default:
 		break;
@@ -2374,7 +2452,10 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 
 	rtw_write8(adapt, REG_SLOT, 0x09);
 
-	value32 = rtw_read32(adapt, REG_TCR);
+	error = rtw_read32(adapt, REG_TCR, &value32);
+	if (error)
+		return;
+
 	value32 &= ~TSFRST;
 	rtw_write32(adapt,  REG_TCR, value32);
 
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 58e852555f54..bcb589777b51 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -152,21 +152,32 @@ static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
 	return res;
 }
 
-static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
 {
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
-	__le32 data;
+	int res;
+	__le32 tmp;
+
+	if (WARN_ON(unlikely(!data)))
+		return -EINVAL;
 
 	requesttype = 0x01;/* read_in */
 
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 4;
 
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	if (res < 0) {
+		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
+	} else {
+		/* Noone cares about positive return value */
+		*data = le32_to_cpu(tmp);
+		res = 0;
+	}
 
-	return le32_to_cpu(data);
+	return res;
 }
 
 static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 2455dae6eebb..bbb1045c9e7d 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -64,7 +64,7 @@ int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
 
 int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data);
 
-u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 *data);
 
 void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data);
 
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index c44554c848cf..501168457518 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -87,7 +87,7 @@ struct io_queue;
 struct _io_ops {
 	int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
 	int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
-	u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+	int (*_read32)(struct intf_hdl *pintfhdl, u32 addr, u32 *data);
 	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
 	int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
 	int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
@@ -250,7 +250,7 @@ void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 
 int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
 int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
-u32 _rtw_read32(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read32(struct adapter *adapter, u32 addr, u32 *data);
 void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_read_port_cancel(struct adapter *adapter);
@@ -272,7 +272,7 @@ void _rtw_write_port_cancel(struct adapter *adapter);
 
 #define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
 #define rtw_read16(adapter, addr, data) _rtw_read16((adapter), (addr), (data))
-#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
+#define rtw_read32(adapter, addr, data) _rtw_read32((adapter), (addr), (data))
 #define rtw_read_mem(adapter, addr, cnt, mem)				\
 	_rtw_read_mem((adapter), (addr), (cnt), (mem))
 #define rtw_read_port(adapter, addr, cnt, mem)				\
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index 79f0fbaa841e..65b240d6c544 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2108,7 +2108,10 @@ static int rtw_wx_read32(struct net_device *dev,
 		sprintf(extra, "0x%04X", data32);
 		break;
 	case 4:
-		data32 = rtw_read32(padapter, addr);
+		error = rtw_read32(padapter, addr, &data32);
+		if (error)
+			return error;
+
 		sprintf(extra, "0x%08X", data32);
 		break;
 	default:
@@ -2278,7 +2281,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 					  (u16 *) &RegRWStruct->value);
 			break;
 		case 4:
-			RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
+			error = rtw_read32(padapter, RegRWStruct->offset, &RegRWStruct->value);
 			break;
 		default:
 			break;
@@ -3818,6 +3821,8 @@ static int rtw_cta_test_start(struct net_device *dev,
 {
 	int ret = 0;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+	int error;
+
 	DBG_88E("%s %s\n", __func__, extra);
 	if (!strcmp(extra, "1"))
 		padapter->in_cta_test = 1;
@@ -3825,12 +3830,22 @@ static int rtw_cta_test_start(struct net_device *dev,
 		padapter->in_cta_test = 0;
 
 	if (padapter->in_cta_test) {
-		u32 v = rtw_read32(padapter, REG_RCR);
+		u32 v;
+
+		error = rtw_read32(padapter, REG_RCR, &v);
+		if (error)
+			return error;
+
 		v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 		rtw_write32(padapter, REG_RCR, v);
 		DBG_88E("enable RCR_ADF\n");
 	} else {
-		u32 v = rtw_read32(padapter, REG_RCR);
+		u32 v;
+
+		error = rtw_read32(padapter, REG_RCR, &v);
+		if (error)
+			return error;
+
 		v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/*  RCR_ADF */
 		rtw_write32(padapter, REG_RCR, v);
 		DBG_88E("disable RCR_ADF\n");
@@ -3900,18 +3915,23 @@ static int rtw_rereg_nd_name(struct net_device *dev,
 static void mac_reg_dump(struct adapter *padapter)
 {
 	int i, j = 1;
+
 	pr_info("\n ======= MAC REG =======\n");
 	for (i = 0x0; i < 0x300; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+		DBG_88E_REG32(" 0x%08x ", padapter, i);
+
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
 	for (i = 0x400; i < 0x800; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+		DBG_88E_REG32(" 0x%08x ", padapter, i);
+
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
@@ -3920,12 +3940,14 @@ static void mac_reg_dump(struct adapter *padapter)
 static void bb_reg_dump(struct adapter *padapter)
 {
 	int i, j = 1;
+
 	pr_info("\n ======= BB REG =======\n");
 	for (i = 0x800; i < 0x1000; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
 
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+		DBG_88E_REG32(" 0x%08x ", padapter, i);
+
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
@@ -3998,7 +4020,8 @@ static int rtw_dbg_port(struct net_device *dev,
 				DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
 			break;
 		case 4:
-			DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+			if (!rtw_read32(padapter, arg, &val32))
+				DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, val32);
 			break;
 		}
 		break;
@@ -4020,7 +4043,9 @@ static int rtw_dbg_port(struct net_device *dev,
 			break;
 		case 4:
 			rtw_write32(padapter, arg, extra_arg);
-			DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+
+			if (!rtw_read32(padapter, arg, &val32))
+				DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, val32);
 			break;
 		}
 		break;
@@ -4178,7 +4203,10 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read32(padapter, reg);
+			error = rtw_read32(padapter, reg, &final);
+			if (error)
+				break;
+
 			if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
 					reg, write_num, start_value, final);
@@ -4460,30 +4488,30 @@ static int rtw_dbg_port(struct net_device *dev,
 			DBG_88E_REG8("rd(0xc58) = 0x%x\n", padapter, 0xc58);
 			break;
 		case 0xff:
-			DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
-			DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
-			DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
-			DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
-			DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
+			DBG_88E_REG32("dbg(0x210) = 0x%x\n", padapter, 0x210);
+			DBG_88E_REG32("dbg(0x608) = 0x%x\n", padapter, 0x608);
+			DBG_88E_REG32("dbg(0x280) = 0x%x\n", padapter, 0x280);
+			DBG_88E_REG32("dbg(0x284) = 0x%x\n", padapter, 0x284);
+			DBG_88E_REG32("dbg(0x288) = 0x%x\n", padapter, 0x288);
 
-			DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
+			DBG_88E_REG32("dbg(0x664) = 0x%x\n", padapter, 0x664);
 
 			DBG_88E("\n");
 
-			DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
-			DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
+			DBG_88E_REG32("dbg(0x430) = 0x%x\n", padapter, 0x430);
+			DBG_88E_REG32("dbg(0x438) = 0x%x\n", padapter, 0x438);
 
-			DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
+			DBG_88E_REG32("dbg(0x440) = 0x%x\n", padapter, 0x440);
 
-			DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
+			DBG_88E_REG32("dbg(0x458) = 0x%x\n", padapter, 0x458);
 
-			DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
-			DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
+			DBG_88E_REG32("dbg(0x484) = 0x%x\n", padapter, 0x484);
+			DBG_88E_REG32("dbg(0x488) = 0x%x\n", padapter, 0x488);
 
-			DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
-			DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
-			DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
-			DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
+			DBG_88E_REG32("dbg(0x444) = 0x%x\n", padapter, 0x444);
+			DBG_88E_REG32("dbg(0x448) = 0x%x\n", padapter, 0x448);
+			DBG_88E_REG32("dbg(0x44c) = 0x%x\n", padapter, 0x44c);
+			DBG_88E_REG32("dbg(0x450) = 0x%x\n", padapter, 0x450);
 			break;
 		}
 		break;
@@ -5434,7 +5462,11 @@ static int rtw_mp_read_reg(struct net_device *dev,
 		break;
 	case 'd':
 		/*  4 bytes */
-		sprintf(data, "%08x", rtw_read32(padapter, addr));
+		error = rtw_read32(padapter, addr, &val32);
+		if (error)
+			return error;
+
+		sprintf(data, "%08x", val32);
 		/* add read data format blank */
 		for (i = 0; i <= strlen(data); i++) {
 			if (i % 2 == 0) {
@@ -6154,14 +6186,14 @@ static int rtw_mp_dump(struct net_device *dev,
 		for (i = 0x0; i < 0x300; i += 4) {
 			if (j % 4 == 1)
 				DBG_88E("0x%02x", i);
-			DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+			DBG_88E_REG32(" 0x%08x ", padapter, i);
 			if ((j++) % 4 == 0)
 				DBG_88E("\n");
 		}
 		for (i = 0x400; i < 0x1000; i += 4) {
 			if (j % 4 == 1)
 				DBG_88E("0x%02x", i);
-			DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+			DBG_88E_REG32(" 0x%08x ", padapter, i);
 			if ((j++) % 4 == 0)
 				DBG_88E("\n");
 		}
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH RFC v2 6/6] staging: r8188eu: make ReadEFuse return an int
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
                                   ` (4 preceding siblings ...)
  2021-08-22 14:36                 ` [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32 Pavel Skripkin
@ 2021-08-22 14:36                 ` Pavel Skripkin
  2021-08-22 15:30                 ` [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
                                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 14:36 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

ReadEFuse can fail in case of _rtw_read() failure. Callers should
handle this error to avoid uninit value bugs, since ReadEFuse
won't initialized passed pbuf in case of usb transfer failure.

To achieve it, ReadEFuseByte() now returns an int and all callers of
ReadEFuseByte() passes error code up to calltrace to rtw_usb_if1_init(),
which fails when reading regiters fails.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_efuse.c      | 45 ++++++++-----
 drivers/staging/r8188eu/hal/hal_intf.c        |  6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 65 ++++++++++++-------
 drivers/staging/r8188eu/hal/usb_halinit.c     | 18 +++--
 drivers/staging/r8188eu/include/hal_intf.h    |  6 +-
 .../staging/r8188eu/include/rtl8188e_hal.h    |  2 +-
 drivers/staging/r8188eu/include/rtw_efuse.h   |  4 +-
 drivers/staging/r8188eu/os_dep/usb_intf.c     |  3 +-
 8 files changed, 96 insertions(+), 53 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index dfe60bc6a547..5bfcf80b2678 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -149,7 +149,7 @@ Efuse_CalculateWordCnts(u8 word_en)
 /*  */
 /* 	Created by Roger, 2008.10.21. */
 /*  */
-void
+int
 ReadEFuseByte(
 		struct adapter *Adapter,
 		u16 _offset,
@@ -163,21 +163,21 @@ ReadEFuseByte(
 
 	if (pseudo) {
 		Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
-		return;
+		return 0;
 	}
 
 	/* Write Address */
 	rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
 	error = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
 	if (error)
-		return;
+		return error;
 
 	rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
 
 	/* Write bit 32 0 */
 	error = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
 	if (error)
-		return;
+		return error;
 
 	rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
 
@@ -185,12 +185,12 @@ ReadEFuseByte(
 	retry = 0;
 	error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
 	if (error)
-		return;
+		return error;
 
 	while (!(((value32 >> 24) & 0xff) & 0x80)  && (retry < 10000)) {
 		error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
 		if (error)
-			return;
+			return error;
 
 		retry++;
 	}
@@ -202,9 +202,11 @@ ReadEFuseByte(
 	udelay(50);
 	error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
 	if (error)
-		return;
+		return error;
 
 	*pbuf = (u8)(value32 & 0xff);
+
+	return 0;
 }
 
 /*  */
@@ -225,9 +227,9 @@ ReadEFuseByte(
 /* 					write addr must be after sec5. */
 /*  */
 
-static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
+static int efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
 {
-	Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
+	return Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
 }
 
 void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
@@ -538,6 +540,7 @@ u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
 u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 {
 	u16 mapLen = 0;
+	int error;
 
 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
 
@@ -546,7 +549,9 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 
 	Efuse_PowerSwitch(padapter, false, true);
 
-	efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+	error = efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+	if (error)
+		return _FAIL;
 
 	Efuse_PowerSwitch(padapter, false, false);
 
@@ -556,6 +561,7 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 {
 	u16 mapLen = 0;
+	int error;
 
 	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
 
@@ -564,7 +570,9 @@ u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 
 	Efuse_PowerSwitch(padapter, false, true);
 
-	efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+	error = efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+	if (error)
+		return _FAIL;
 
 	Efuse_PowerSwitch(padapter, false, false);
 
@@ -835,17 +843,22 @@ efuse_ShadowRead4Byte(
  * 11/11/2008	MHC		Create Version 0.
  *
  *---------------------------------------------------------------------------*/
-static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
+static int Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
 {
 	u16 mapLen = 0;
+	int error;
 
 	Efuse_PowerSwitch(pAdapter, false, true);
 
 	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
 
-	efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+	error = efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+	if (error)
+		return error;
 
 	Efuse_PowerSwitch(pAdapter, false, false);
+
+	return 0;
 }
 
 /*-----------------------------------------------------------------------------
@@ -864,7 +877,7 @@ static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse,
  * 11/13/2008	MHC		Create Version 0.
  *
  *---------------------------------------------------------------------------*/
-void EFUSE_ShadowMapUpdate(
+int EFUSE_ShadowMapUpdate(
 	struct adapter *pAdapter,
 	u8 efuseType,
 	bool pseudo)
@@ -877,7 +890,9 @@ void EFUSE_ShadowMapUpdate(
 	if (pEEPROM->bautoload_fail_flag)
 		memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
 	else
-		Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+		return Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+
+	return 0;
 } /*  EFUSE_ShadowMapUpdate */
 
 /*-----------------------------------------------------------------------------
diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c
index a6d589e89aeb..dce9a58eaf6f 100644
--- a/drivers/staging/r8188eu/hal/hal_intf.c
+++ b/drivers/staging/r8188eu/hal/hal_intf.c
@@ -12,10 +12,12 @@ void rtw_hal_chip_configure(struct adapter *adapt)
 		adapt->HalFunc.intf_chip_configure(adapt);
 }
 
-void rtw_hal_read_chip_info(struct adapter *adapt)
+int rtw_hal_read_chip_info(struct adapter *adapt)
 {
 	if (adapt->HalFunc.read_adapter_info)
-		adapt->HalFunc.read_adapter_info(adapt);
+		return adapt->HalFunc.read_adapter_info(adapt);
+
+	return _FAIL;
 }
 
 void rtw_hal_read_chip_version(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 69649a381727..41cf432398e2 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -871,7 +871,7 @@ rtl8188e_EfusePowerSwitch(
 	hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
 }
 
-static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
+static int Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	u16			_offset,
 	u16			_size_byte,
 	u8 *pbuf,
@@ -886,24 +886,26 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	u16	**eFuseWord = NULL;
 	u16	efuse_utilized = 0;
 	u8 u1temp = 0;
+	int error = 0;
 
 	/*  */
 	/*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
 	/*  */
 	if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {/*  total E-Fuse table is 512bytes */
 		DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
-		goto exit;
+		return -EINVAL;
 	}
 
 	efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
 	if (!efuseTbl) {
 		DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
-		goto exit;
+		return -ENOMEM;
 	}
 
 	eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
 	if (!eFuseWord) {
 		DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
+		error = -ENOMEM;
 		goto exit;
 	}
 
@@ -916,12 +918,16 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	/*  1. Read the first byte to check if efuse is empty!!! */
 	/*  */
 	/*  */
-	ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+	error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+	if (error)
+		goto exit;
+
 	if (*rtemp8 != 0xFF) {
 		efuse_utilized++;
 		eFuse_Addr++;
 	} else {
 		DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
+		error = -EAGAIN;
 		goto exit;
 	}
 
@@ -933,11 +939,15 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 		if ((*rtemp8 & 0x1F) == 0x0F) {		/* extended header */
 			u1temp = ((*rtemp8 & 0xE0) >> 5);
 
-			ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+			error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+			if (error)
+				goto exit;
 
 			if ((*rtemp8 & 0x0F) == 0x0F) {
 				eFuse_Addr++;
-				ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+				error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+				if (error)
+					goto exit;
 
 				if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
 					eFuse_Addr++;
@@ -958,13 +968,19 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
 				/*  Check word enable condition in the section */
 				if (!(wren & 0x01)) {
-					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					if (error)
+						goto exit;
+
 					eFuse_Addr++;
 					efuse_utilized++;
 					eFuseWord[offset][i] = (*rtemp8 & 0xff);
 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
 						break;
-					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					if (error)
+						goto exit;
+
 					eFuse_Addr++;
 					efuse_utilized++;
 					eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
@@ -976,7 +992,9 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 		}
 
 		/*  Read next PG header */
-		ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+		error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+		if (error)
+			goto exit;
 
 		if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
 			efuse_utilized++;
@@ -1002,9 +1020,11 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 exit:
 	kfree(efuseTbl);
 	kfree(eFuseWord);
+
+	return error;
 }
 
-static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
 {
 	if (!bPseudoTest) {
 		int ret = _FAIL;
@@ -1016,28 +1036,25 @@ static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u1
 			iol_mode_enable(Adapter, 0);
 
 			if (_SUCCESS == ret)
-				goto exit;
+				return 0;
 		}
 	}
-	Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
-
-exit:
-	return;
+	return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
 }
 
-static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
 {
-	Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+	return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
 }
 
-static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
+static int rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
 			       u16 _offset, u16 _size_byte, u8 *pbuf,
 			       bool bPseudoTest)
 {
 	if (bPseudoTest)
-		ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+		return ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
 	else
-		ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+		return ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
 }
 
 /* Do not support BT */
@@ -2045,7 +2062,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
 	return status;
 }
 
-void
+int
 Hal_InitPGData88E(struct adapter *padapter)
 {
 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
@@ -2053,13 +2070,15 @@ Hal_InitPGData88E(struct adapter *padapter)
 	if (!pEEPROM->bautoload_fail_flag) { /*  autoload OK. */
 		if (!is_boot_from_eeprom(padapter)) {
 			/*  Read EFUSE real map to shadow. */
-			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+			return EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
 		}
 	} else {/* autoload fail */
 		/* update to default value 0xFF */
 		if (!is_boot_from_eeprom(padapter))
-			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+			return EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
 	}
+
+	return 0;
 }
 
 void
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 3826476e3396..687baf4d9d97 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -1296,7 +1296,7 @@ readAdapterInfo_8188EU(
 	_ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
 }
 
-static void _ReadPROMContent(
+static int _ReadPROMContent(
 	struct adapter *Adapter
 	)
 {
@@ -1307,7 +1307,7 @@ static void _ReadPROMContent(
 	/* check system boot selection */
 	error = rtw_read8(Adapter, REG_9346CR, &eeValue);
 	if (error)
-		return;
+		return error;
 
 	eeprom->EepromOrEfuse		= (eeValue & BOOT_FROM_EEPROM) ? true : false;
 	eeprom->bautoload_fail_flag	= (eeValue & EEPROM_EN) ? false : true;
@@ -1315,8 +1315,13 @@ static void _ReadPROMContent(
 	DBG_88E("Boot from %s, Autoload %s !\n", (eeprom->EepromOrEfuse ? "EEPROM" : "EFUSE"),
 		(eeprom->bautoload_fail_flag ? "Fail" : "OK"));
 
-	Hal_InitPGData88E(Adapter);
+	error = Hal_InitPGData88E(Adapter);
+	if (error)
+		return error;
+
 	readAdapterInfo_8188EU(Adapter);
+
+	return 0;
 }
 
 static void _ReadRFType(struct adapter *Adapter)
@@ -1333,19 +1338,20 @@ static int _ReadAdapterInfo8188EU(struct adapter *Adapter)
 	MSG_88E("====> %s\n", __func__);
 
 	_ReadRFType(Adapter);/* rf_chip -> _InitRFType() */
-	_ReadPROMContent(Adapter);
+	if (_ReadPROMContent(Adapter))
+		return _FAIL;
 
 	MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
 
 	return _SUCCESS;
 }
 
-static void ReadAdapterInfo8188EU(struct adapter *Adapter)
+static int ReadAdapterInfo8188EU(struct adapter *Adapter)
 {
 	/*  Read EEPROM size before call any EEPROM function */
 	Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter);
 
-	_ReadAdapterInfo8188EU(Adapter);
+	return _ReadAdapterInfo8188EU(Adapter);
 }
 
 #define GPIO_DEBUG_PORT_NUM 0
diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h
index fa252540e596..9241af39e3a3 100644
--- a/drivers/staging/r8188eu/include/hal_intf.h
+++ b/drivers/staging/r8188eu/include/hal_intf.h
@@ -154,7 +154,7 @@ struct hal_ops {
 
 	void	(*intf_chip_configure)(struct adapter *padapter);
 
-	void	(*read_adapter_info)(struct adapter *padapter);
+	int	(*read_adapter_info)(struct adapter *padapter);
 
 	void	(*enable_interrupt)(struct adapter *padapter);
 	void	(*disable_interrupt)(struct adapter *padapter);
@@ -222,7 +222,7 @@ struct hal_ops {
 
 	void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite,
 				 u8 PwrState);
-	void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
+	int (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
 			  u16 _size_byte, u8 *pbuf, bool bPseudoTest);
 	void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType,
 					u8 type, void *pOut, bool bPseudoTest);
@@ -324,7 +324,7 @@ void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val);
 void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val);
 
 void rtw_hal_chip_configure(struct adapter *padapter);
-void rtw_hal_read_chip_info(struct adapter *padapter);
+int rtw_hal_read_chip_info(struct adapter *padapter);
 void rtw_hal_read_chip_version(struct adapter *padapter);
 
 u8 rtw_hal_set_def_var(struct adapter *padapter,
diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h
index 3939bf053de1..db9adbd0b024 100644
--- a/drivers/staging/r8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h
@@ -410,7 +410,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
 
 /*  EFuse */
 u8 GetEEPROMSize8188E(struct adapter *padapter);
-void Hal_InitPGData88E(struct adapter *padapter);
+int Hal_InitPGData88E(struct adapter *padapter);
 void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
 void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
 			    bool AutoLoadFail);
diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h
index b3ff46db2091..9657b66679e3 100644
--- a/drivers/staging/r8188eu/include/rtw_efuse.h
+++ b/drivers/staging/r8188eu/include/rtw_efuse.h
@@ -113,7 +113,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr,
 			  u16 cnts, u8 *data);
 u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test);
 u8 Efuse_CalculateWordCnts(u8 word_en);
-void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
+int ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
 void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1,
 			      void *out, bool bPseudoTest);
 u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test);
@@ -128,7 +128,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr,
 			     u8 word_en, u8 *data, bool test);
 
 u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address);
-void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
+int EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
 void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val);
 
 #endif
diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c
index e002070f7fba..7a1a296f66b5 100644
--- a/drivers/staging/r8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/r8188eu/os_dep/usb_intf.c
@@ -608,7 +608,8 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
 	rtw_hal_chip_configure(padapter);
 
 	/* step read efuse/eeprom data and get mac_addr */
-	rtw_hal_read_chip_info(padapter);
+	if (rtw_hal_read_chip_info(padapter) == _FAIL)
+		goto free_hal_data;
 
 	/* step 5. */
 	if (rtw_init_drv_sw(padapter) == _FAIL)
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 13:21           ` Fabio M. De Francesco
  2021-08-22 13:30             ` Greg KH
  2021-08-22 13:31             ` Pavel Skripkin
@ 2021-08-22 15:04             ` Phillip Potter
  2 siblings, 0 replies; 118+ messages in thread
From: Phillip Potter @ 2021-08-22 15:04 UTC (permalink / raw)
  To: Fabio M. De Francesco
  Cc: Pavel Skripkin, Greg KH, Larry Finger, Michael Straube,
	linux-staging, Linux Kernel Mailing List, Martin Kaiser

On Sun, 22 Aug 2021 at 14:21, Fabio M. De Francesco
<fmdefrancesco@gmail.com> wrote:
>
> On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
> > On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> > > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> > > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> [...]
> > > > So, it's up to the callers to test if (!_rtw_read*()) and then act
> > > > accordingly. If they get 0 they should know how to handle the errors.
> > >
> > > Yes, but _rtw_read*() == 0 indicates 2 states:
> > >     1. Error on transfer side
> > >     2. Actual register value is 0
> >
> > That's not a good design, it should be fixed.  Note there is the new
> > usb_control_msg_recv() function which should probably be used instead
> > here, to prevent this problem from happening.
>
> I think that no functions should return 0 for signaling FAILURE. If I'm not
> wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
> FAILURE. Why don't you just fix this?
>
> > > > In summation. if anything should be changed, it is the code of the
> callers of
> > > > _rtw_read*() if you find out they they don't properly handle the
> returning
> > > > values of this function. You should find every place where _rtw_read*()
> are
> > > > called and figure out if the returns are properly checked and handled;
> if not,
> > > > make some change only there.
> > > >
> > > > Larry, Philip, where are you? Am I missing something?
> >
> > Relax, there is no need to get jumpy, people do not have to respond
> > instantly to emails here.  Especially when it is not their job to do so.
>
> I should have placed a big smile at the end of the phrase. I was just kidding
> while trying to get their attention. I know there is no hurry and that no one
> has any obligation of this kind. Again, just kidding :)
>
> Thanks,
>
> Fabio
>
> > greg k-h
>
>
>
>

Dear Fabio,

I can't speak for anyone else, but I will reply to as many e-mails as
I'm able - there is no need to try and get my attention, you shall
have it by default, as and when I am able to give it :-)

As V2 has been sent out by Pavel, I will try and take a look soon.

Regards,
Phil

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
                                   ` (5 preceding siblings ...)
  2021-08-22 14:36                 ` [PATCH RFC v2 6/6] staging: r8188eu: make ReadEFuse return an int Pavel Skripkin
@ 2021-08-22 15:30                 ` Pavel Skripkin
  2021-08-22 16:05                   ` Michael Straube
  2021-08-22 17:36                 ` Fabio M. De Francesco
  2021-08-23  0:12                 ` Phillip Potter
  8 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 15:30 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel

On 8/22/21 5:35 PM, Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
> 
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
> 
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
> 
> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
> 
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
> 
> Why is this pacth series RFC?
>    1. I don't have this device and I cannot test these changes.
>    2. I don't know how to handle errors in each particular case. For now, function
>       just returns or returns an error. That's all. I hope, driver maintainers will
>       help with these bits.
>    3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>       at least half of them
> 
> 
> v1 -> v2:
>    1. Make rtw_read*() return an error instead of initializing pointer to error
>    2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>       changes
>    3. Add new macro for printing register values (It helps to not copy-paste error
>       handling)
>    4. Removed {read,write}_macreg (Suggested by Phillip)
>    5. Rebased on top of staging-next
>    6. Cleaned checkpatch errors and warnings
> 
> Only build-tested, since I don't have device with r8118eu chip
> 

BTW, can you recommend any devices with this chip except for ASUS 
USB-N10 Nano? I didn't find any of them with delivery/reasonable 
delivery price to Russia.

I want to help with testing and moving this driver out of staging 
directory :)



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 13:31             ` Pavel Skripkin
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
@ 2021-08-22 16:03               ` Fabio M. De Francesco
  2021-08-22 16:15                 ` Pavel Skripkin
  1 sibling, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-22 16:03 UTC (permalink / raw)
  To: Greg KH, Pavel Skripkin
  Cc: Larry.Finger, phil, straube.linux, linux-staging, linux-kernel,
	Martin Kaiser

On Sunday, August 22, 2021 3:31:31 PM CEST Pavel Skripkin wrote:
> On 8/22/21 4:21 PM, Fabio M. De Francesco wrote:
> > On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
> >> On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
> >> > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
> >> > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
> > [...]
> >> > > So, it's up to the callers to test if (!_rtw_read*()) and then act
> >> > > accordingly. If they get 0 they should know how to handle the errors.
> >> > 
> >> > Yes, but _rtw_read*() == 0 indicates 2 states:
> >> > 	1. Error on transfer side
> >> > 	2. Actual register value is 0
> >> 
> >> That's not a good design, it should be fixed.  Note there is the new
> >> usb_control_msg_recv() function which should probably be used instead
> >> here, to prevent this problem from happening.
> > 
> > I think that no functions should return 0 for signaling FAILURE. If I'm not
> > wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
> > FAILURE. Why don't you just fix this?
> > 
> That's what I've done in v2. All rtw_read* family will have following 
> prototype in v2:
> 
> int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
> 
> Was it your idea, or you were talking about different approach?
> 
> With regards,
> Pavel Skripkin

Pavel,

Yes, it is correct.

However, after that I had time to look at the calls chain and understand what 
each function does and then I saw that my initial proposal should be made
along with another one...

The calls chain is:

(1)        _rtw_read8()  <--- (returns the data read from next function in chain) 
                                            (no errors returned, see possible fix in next function)
(2)                usb_read8() <--- (returns the data read from next function in chain) 
                                                 (_data_may_be_unitialised_, no errors returned)
		  (possible fix: from "u8 data"; to "char data = -1;")
(3)                           usbctrl_vendorreq() <---- (returns data read from next function in chain)
		                            (data is always a valid pointer saved to third argument)
		                            (if it fails, the third argument is unchanged because it
		                            still has the address of the "data" argument given by the caller)
(4)	                usb_control_msg() <---- (it always returns how many bytes read or valid error codes)
		                                  (it _never_ returns 0: either positive or negative values)
		
I have not yet looked at the usb_control_msg_recv() which Greg talked about.

To summarize: in function (2) "u8 data" should become "char data = -1;".

Regards,

Fabio

P.S.: I was about to send this message while I see that you sent v2. Since I've already have
this response to your question I send it and soon after I'm going to read your v2 patches. 
 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 15:30                 ` [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
@ 2021-08-22 16:05                   ` Michael Straube
  2021-08-22 16:26                     ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: Michael Straube @ 2021-08-22 16:05 UTC (permalink / raw)
  To: Pavel Skripkin, Larry.Finger, phil, gregkh, fmdefrancesco
  Cc: linux-staging, linux-kernel

On 8/22/21 5:30 PM, Pavel Skripkin wrote:
> BTW, can you recommend any devices with this chip except for ASUS 
> USB-N10 Nano? I didn't find any of them with delivery/reasonable 
> delivery price to Russia.
> 
> I want to help with testing and moving this driver out of staging 
> directory :)

Hi Pavel,

My one is a TP-LINK WN725N (not sure, but I guess v2).
You could also have a look at the device table in os_dep/usb_intf.c

Regards,
Michael

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC 0/3] staging: r8188eu: avoid uninit value bugs
  2021-08-22 16:03               ` [PATCH RFC 0/3] " Fabio M. De Francesco
@ 2021-08-22 16:15                 ` Pavel Skripkin
  0 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 16:15 UTC (permalink / raw)
  To: Fabio M. De Francesco, Greg KH
  Cc: Larry.Finger, phil, straube.linux, linux-staging, linux-kernel,
	Martin Kaiser

On 8/22/21 7:03 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 3:31:31 PM CEST Pavel Skripkin wrote:
>> On 8/22/21 4:21 PM, Fabio M. De Francesco wrote:
>> > On Sunday, August 22, 2021 2:39:34 PM CEST Greg KH wrote:
>> >> On Sun, Aug 22, 2021 at 03:10:56PM +0300, Pavel Skripkin wrote:
>> >> > On 8/22/21 1:59 PM, Fabio M. De Francesco wrote:
>> >> > > On Sunday, August 22, 2021 12:09:29 PM CEST Pavel Skripkin wrote:
>> > [...]
>> >> > > So, it's up to the callers to test if (!_rtw_read*()) and then act
>> >> > > accordingly. If they get 0 they should know how to handle the errors.
>> >> > 
>> >> > Yes, but _rtw_read*() == 0 indicates 2 states:
>> >> > 	1. Error on transfer side
>> >> > 	2. Actual register value is 0
>> >> 
>> >> That's not a good design, it should be fixed.  Note there is the new
>> >> usb_control_msg_recv() function which should probably be used instead
>> >> here, to prevent this problem from happening.
>> > 
>> > I think that no functions should return 0 for signaling FAILURE. If I'm not
>> > wrong, the kernel quite always prefers to return 0 on SUCCESS and <0 on
>> > FAILURE. Why don't you just fix this?
>> > 
>> That's what I've done in v2. All rtw_read* family will have following 
>> prototype in v2:
>> 
>> int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
>> 

(*)

>> Was it your idea, or you were talking about different approach?
>> 
>> With regards,
>> Pavel Skripkin
> 
> Pavel,
> 
> Yes, it is correct.
> 
> However, after that I had time to look at the calls chain and understand what
> each function does and then I saw that my initial proposal should be made
> along with another one...
> 
> The calls chain is:
> 
> (1)        _rtw_read8()  <--- (returns the data read from next function in chain)
>                                              (no errors returned, see possible fix in next function)
> (2)                usb_read8() <--- (returns the data read from next function in chain)
>                                                   (_data_may_be_unitialised_, no errors returned)
> 		  (possible fix: from "u8 data"; to "char data = -1;")

Anyway char will be cast to u8 and -1 will become 0xff. 0xff is still 
valid register value, I guess.

> (3)                           usbctrl_vendorreq() <---- (returns data read from next function in chain)
> 		                            (data is always a valid pointer saved to third argument)
> 		                            (if it fails, the third argument is unchanged because it
> 		                            still has the address of the "data" argument given by the caller) > (4)	                usb_control_msg() <---- (it always returns how 
many bytes read or valid error codes)
> 		                                  (it _never_ returns 0: either positive or negative values)
> 		
> I have not yet looked at the usb_control_msg_recv() which Greg talked about.
> 
> To summarize: in function (2) "u8 data" should become "char data = -1;".
> 

So, anyway caller _should_ somehow receive an error from 
usb_control_msg(). We can just change rtw_read{8,16,32} return values 
from u{8,16,32} to int32, but anyway it will require all changes, that 
I've done in this series, but in slightly different form. I.e temp int32 
variable + error checking + casting int to u{8,16,32}.

Doesn't it make sense to just switch to more standard prototype (*)? All 
other drivers use this prototype for their private reading functions.



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 16:05                   ` Michael Straube
@ 2021-08-22 16:26                     ` Pavel Skripkin
  2021-08-22 23:52                       ` Phillip Potter
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 16:26 UTC (permalink / raw)
  To: Michael Straube, Larry.Finger, phil, gregkh, fmdefrancesco
  Cc: linux-staging, linux-kernel

On 8/22/21 7:05 PM, Michael Straube wrote:

> Hi Pavel,
> 
> My one is a TP-LINK WN725N (not sure, but I guess v2).

Wow! I found this one in my city, thank you!

> You could also have a look at the device table in os_dep/usb_intf.c
> 

Yep, but I wanted to hear from driver reviewers/maintainers about what 
they use to test. I guess, some devices could be broken or not unwieldy 
to use. Thank you for recommendation, will buy one in few days :)



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
                                   ` (6 preceding siblings ...)
  2021-08-22 15:30                 ` [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
@ 2021-08-22 17:36                 ` Fabio M. De Francesco
  2021-08-22 17:38                   ` Pavel Skripkin
  2021-08-23  0:12                 ` Phillip Potter
  8 siblings, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-22 17:36 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel, Pavel Skripkin

On Sunday, August 22, 2021 4:35:05 PM CEST Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
> 
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
> 
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
> 
> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
> 
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
> 
> Why is this pacth series RFC?
>   1. I don't have this device and I cannot test these changes.
>   2. I don't know how to handle errors in each particular case. For now, function
>      just returns or returns an error. That's all. I hope, driver maintainers will
>      help with these bits.
>   3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>      at least half of them
> 
> v1 -> v2:
>   1. Make rtw_read*() return an error instead of initializing pointer to error
>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>      changes
>   3. Add new macro for printing register values (It helps to not copy-paste error
>      handling)
>   4. Removed {read,write}_macreg (Suggested by Phillip)
>   5. Rebased on top of staging-next
>   6. Cleaned checkpatch errors and warnings
> 
> Only build-tested, since I don't have device with r8118eu chip
> 
> Pavel Skripkin (6):
>   staging: r8188eu: remove {read,write}_macreg
>   staging: r8188eu: add helper macro for printing registers
>   staging: r8188eu: add error handling of rtw_read8
>   staging: r8188eu: add error handling of rtw_read16
>   staging: r8188eu: add error handling of rtw_read32
>   staging: r8188eu: make ReadEFuse return an int

Hi Pavel,

I've just read your v2 of the series. I had no time to read each and every line, 
however, I suppose that I saw enough to say that I think they are a huge 
improvement over v1. I really like your patches and if I were you, I'd drop
that RFC tag.

Thanks,

Fabio
v1 design.
not needed because 



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 17:36                 ` Fabio M. De Francesco
@ 2021-08-22 17:38                   ` Pavel Skripkin
  2021-08-22 20:06                     ` Fabio M. De Francesco
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 17:38 UTC (permalink / raw)
  To: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux
  Cc: linux-staging, linux-kernel

On 8/22/21 8:36 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 4:35:05 PM CEST Pavel Skripkin wrote:
>> Hi, Greg, Larry and Phillip!
>> 
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>> 
>> The first thing I noticed is *no one* was checking read operations result, but
>> it can fail and driver may start writing random stack values into registers. It
>> can cause driver misbehavior or device misbehavior.
>> 
>> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
>> funtions return an error, when something went wrong with usb transfer.
>> 
>> It helps callers to break/return earlier and don't write random values to
>> registers or to rely on random values.
>> 
>> Why is this pacth series RFC?
>>   1. I don't have this device and I cannot test these changes.
>>   2. I don't know how to handle errors in each particular case. For now, function
>>      just returns or returns an error. That's all. I hope, driver maintainers will
>>      help with these bits.
>>   3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>>      at least half of them
>> 
>> v1 -> v2:
>>   1. Make rtw_read*() return an error instead of initializing pointer to error
>>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>>      changes
>>   3. Add new macro for printing register values (It helps to not copy-paste error
>>      handling)
>>   4. Removed {read,write}_macreg (Suggested by Phillip)
>>   5. Rebased on top of staging-next
>>   6. Cleaned checkpatch errors and warnings
>> 
>> Only build-tested, since I don't have device with r8118eu chip
>> 
>> Pavel Skripkin (6):
>>   staging: r8188eu: remove {read,write}_macreg
>>   staging: r8188eu: add helper macro for printing registers
>>   staging: r8188eu: add error handling of rtw_read8
>>   staging: r8188eu: add error handling of rtw_read16
>>   staging: r8188eu: add error handling of rtw_read32
>>   staging: r8188eu: make ReadEFuse return an int
> 
> Hi Pavel,
> 
> I've just read your v2 of the series. I had no time to read each and every line,
> however, I suppose that I saw enough to say that I think they are a huge
> improvement over v1. I really like your patches and if I were you, I'd drop
> that RFC tag.
> 

Thank you, Fabio! I appreciate it :)


With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 17:38                   ` Pavel Skripkin
@ 2021-08-22 20:06                     ` Fabio M. De Francesco
  2021-08-22 20:19                       ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-22 20:06 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel

On Sunday, August 22, 2021 7:38:11 PM CEST Pavel Skripkin wrote:
> On 8/22/21 8:36 PM, Fabio M. De Francesco wrote:
> > On Sunday, August 22, 2021 4:35:05 PM CEST Pavel Skripkin wrote:
> >> Hi, Greg, Larry and Phillip!
> >> 
> >> I noticed, that new staging driver was added like 3 weeks ago and I decided
> >> to look at the code, because drivers in staging directory are always buggy.
> >> 
> >> The first thing I noticed is *no one* was checking read operations result, but
> >> it can fail and driver may start writing random stack values into registers. It
> >> can cause driver misbehavior or device misbehavior.
> >> 
> >> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
> >> funtions return an error, when something went wrong with usb transfer.
> >> 
> >> It helps callers to break/return earlier and don't write random values to
> >> registers or to rely on random values.
> >> 
> >> Why is this pacth series RFC?
> >>   1. I don't have this device and I cannot test these changes.
> >>   2. I don't know how to handle errors in each particular case. For now, function
> >>      just returns or returns an error. That's all. I hope, driver maintainers will
> >>      help with these bits.
> >>   3. I guess, I handled not all uninit value bugs here. I hope, I fixed
> >>      at least half of them
> >> 
> >> v1 -> v2:
> >>   1. Make rtw_read*() return an error instead of initializing pointer to error
> >>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
> >>      changes
> >>   3. Add new macro for printing register values (It helps to not copy-paste error
> >>      handling)
> >>   4. Removed {read,write}_macreg (Suggested by Phillip)
> >>   5. Rebased on top of staging-next
> >>   6. Cleaned checkpatch errors and warnings
> >> 
> >> Only build-tested, since I don't have device with r8118eu chip
> >> 
> >> Pavel Skripkin (6):
> >>   staging: r8188eu: remove {read,write}_macreg
> >>   staging: r8188eu: add helper macro for printing registers
> >>   staging: r8188eu: add error handling of rtw_read8
> >>   staging: r8188eu: add error handling of rtw_read16
> >>   staging: r8188eu: add error handling of rtw_read32
> >>   staging: r8188eu: make ReadEFuse return an int
> > 
> > Hi Pavel,
> > 
> > I've just read your v2 of the series. I had no time to read each and every line,
> > however, I suppose that I saw enough to say that I think they are a huge
> > improvement over v1. I really like your patches and if I were you, I'd drop
> > that RFC tag.
> > 
> 
> Thank you, Fabio! I appreciate it :)
> 
> 
> With regards,
> Pavel Skripkin

Hi Pavel,

I've read more code of your series and I'm ready to give a formal ack. However,
I'm not sure about the rules: can it be also given to RFC or only to "real" patches?

As I've already said, they look good and I like them. So, the entire series is...

Acked-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>

If the rules don't allow to formally ack RFC, I will be happy to ack again the final product.

I also want to say that I enjoyed discussing this work with you on this long thread. :-)

Thanks,

Fabio

 




^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 20:06                     ` Fabio M. De Francesco
@ 2021-08-22 20:19                       ` Pavel Skripkin
  0 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-22 20:19 UTC (permalink / raw)
  To: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux
  Cc: linux-staging, linux-kernel

On 8/22/21 11:06 PM, Fabio M. De Francesco wrote:
> On Sunday, August 22, 2021 7:38:11 PM CEST Pavel Skripkin wrote:
>> On 8/22/21 8:36 PM, Fabio M. De Francesco wrote:
>> > On Sunday, August 22, 2021 4:35:05 PM CEST Pavel Skripkin wrote:
>> >> Hi, Greg, Larry and Phillip!
>> >> 
>> >> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> >> to look at the code, because drivers in staging directory are always buggy.
>> >> 
>> >> The first thing I noticed is *no one* was checking read operations result, but
>> >> it can fail and driver may start writing random stack values into registers. It
>> >> can cause driver misbehavior or device misbehavior.
>> >> 
>> >> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
>> >> funtions return an error, when something went wrong with usb transfer.
>> >> 
>> >> It helps callers to break/return earlier and don't write random values to
>> >> registers or to rely on random values.
>> >> 
>> >> Why is this pacth series RFC?
>> >>   1. I don't have this device and I cannot test these changes.
>> >>   2. I don't know how to handle errors in each particular case. For now, function
>> >>      just returns or returns an error. That's all. I hope, driver maintainers will
>> >>      help with these bits.
>> >>   3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>> >>      at least half of them
>> >> 
>> >> v1 -> v2:
>> >>   1. Make rtw_read*() return an error instead of initializing pointer to error
>> >>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>> >>      changes
>> >>   3. Add new macro for printing register values (It helps to not copy-paste error
>> >>      handling)
>> >>   4. Removed {read,write}_macreg (Suggested by Phillip)
>> >>   5. Rebased on top of staging-next
>> >>   6. Cleaned checkpatch errors and warnings
>> >> 
>> >> Only build-tested, since I don't have device with r8118eu chip
>> >> 
>> >> Pavel Skripkin (6):
>> >>   staging: r8188eu: remove {read,write}_macreg
>> >>   staging: r8188eu: add helper macro for printing registers
>> >>   staging: r8188eu: add error handling of rtw_read8
>> >>   staging: r8188eu: add error handling of rtw_read16
>> >>   staging: r8188eu: add error handling of rtw_read32
>> >>   staging: r8188eu: make ReadEFuse return an int
>> > 
>> > Hi Pavel,
>> > 
>> > I've just read your v2 of the series. I had no time to read each and every line,
>> > however, I suppose that I saw enough to say that I think they are a huge
>> > improvement over v1. I really like your patches and if I were you, I'd drop
>> > that RFC tag.
>> > 
>> 
>> Thank you, Fabio! I appreciate it :)
>> 
>> 
>> With regards,
>> Pavel Skripkin
> 
> Hi Pavel,
> 
> I've read more code of your series and I'm ready to give a formal ack. However,
> I'm not sure about the rules: can it be also given to RFC or only to "real" patches?
> 
> As I've already said, they look good and I like them. So, the entire series is...
> 

AFAIK, RFC patches can be treated as normal patches, if 
reviewers/maintainers don't have objections to code. I am not sure about 
it, since it's my first experience with RFCs :)

Anyway, thank you for ACKing. Let's see what Larry thinks about it. I 
believe, he can find some bugs in my code since it's not tested at all 
:) I hope, my r8118eu device will come soon and I will be able to test 
this series...

> Acked-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
> 
> If the rules don't allow to formally ack RFC, I will be happy to ack again the final product.
> 
> I also want to say that I enjoyed discussing this work with you on this long thread. :-)
> 

Me too, thank you. Technical discussions are the best part of linux 
kernel development process, IMO :)



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 16:26                     ` Pavel Skripkin
@ 2021-08-22 23:52                       ` Phillip Potter
  0 siblings, 0 replies; 118+ messages in thread
From: Phillip Potter @ 2021-08-22 23:52 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Michael Straube, Larry Finger, Greg KH, Fabio M. De Francesco,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On Sun, 22 Aug 2021 at 17:26, Pavel Skripkin <paskripkin@gmail.com> wrote:
>
> On 8/22/21 7:05 PM, Michael Straube wrote:
>
> > Hi Pavel,
> >
> > My one is a TP-LINK WN725N (not sure, but I guess v2).
>
> Wow! I found this one in my city, thank you!
>
> > You could also have a look at the device table in os_dep/usb_intf.c
> >
>
> Yep, but I wanted to hear from driver reviewers/maintainers about what
> they use to test. I guess, some devices could be broken or not unwieldy
> to use. Thank you for recommendation, will buy one in few days :)
>
>
>
> With regards,
> Pavel Skripkin

Dear Pavel,

Glad you found one :-) Mine is the N10-Nano as that was all I could
find at the time.

Regards,
Phil

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-22 14:35               ` [PATCH RFC v2 0/6] " Pavel Skripkin
                                   ` (7 preceding siblings ...)
  2021-08-22 17:36                 ` Fabio M. De Francesco
@ 2021-08-23  0:12                 ` Phillip Potter
  2021-08-23  6:38                   ` Pavel Skripkin
  2021-08-23  6:44                   ` Pavel Skripkin
  8 siblings, 2 replies; 118+ messages in thread
From: Phillip Potter @ 2021-08-23  0:12 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry Finger, Greg KH, Michael Straube, Fabio M. De Francesco,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On Sun, 22 Aug 2021 at 15:35, Pavel Skripkin <paskripkin@gmail.com> wrote:
>
> Hi, Greg, Larry and Phillip!
>
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
>
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
>
> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
>
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
>
> Why is this pacth series RFC?
>   1. I don't have this device and I cannot test these changes.
>   2. I don't know how to handle errors in each particular case. For now, function
>      just returns or returns an error. That's all. I hope, driver maintainers will
>      help with these bits.
>   3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>      at least half of them
>
>
> v1 -> v2:
>   1. Make rtw_read*() return an error instead of initializing pointer to error
>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>      changes
>   3. Add new macro for printing register values (It helps to not copy-paste error
>      handling)
>   4. Removed {read,write}_macreg (Suggested by Phillip)
>   5. Rebased on top of staging-next
>   6. Cleaned checkpatch errors and warnings
>
> Only build-tested, since I don't have device with r8118eu chip
>
> Pavel Skripkin (6):
>   staging: r8188eu: remove {read,write}_macreg
>   staging: r8188eu: add helper macro for printing registers
>   staging: r8188eu: add error handling of rtw_read8
>   staging: r8188eu: add error handling of rtw_read16
>   staging: r8188eu: add error handling of rtw_read32
>   staging: r8188eu: make ReadEFuse return an int
>
>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>  drivers/staging/r8188eu/core/rtw_efuse.c      | 125 +++--
>  drivers/staging/r8188eu/core/rtw_io.c         |  27 +-
>  drivers/staging/r8188eu/core/rtw_mp.c         |  70 ++-
>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  13 +-
>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   5 +-
>  drivers/staging/r8188eu/core/rtw_sreset.c     |   9 +-
>  .../r8188eu/hal/Hal8188ERateAdaptive.c        |   8 +-
>  drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |  21 +-
>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>  drivers/staging/r8188eu/hal/hal_com.c         |  23 +-
>  drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  33 +-
>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 285 +++++++++---
>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  27 +-
>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  22 +-
>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  18 +-
>  drivers/staging/r8188eu/hal/usb_halinit.c     | 439 +++++++++++++++---
>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  57 ++-
>  drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
>  .../staging/r8188eu/include/odm_interface.h   |   6 +-
>  .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
>  drivers/staging/r8188eu/include/rtw_debug.h   |  13 +
>  drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>  drivers/staging/r8188eu/include/rtw_mp.h      |   2 -
>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 179 +++++--
>  drivers/staging/r8188eu/os_dep/usb_intf.c     |   3 +-
>  30 files changed, 1138 insertions(+), 389 deletions(-)
>
> --
> 2.32.0
>

Dear Pavel,

Thanks for this. I like the code a lot. One thing I am conflicted on
is the helper macro for the printing of register values though. Whilst
I'm not necessarily opposed to the concept of the macro itself, I
don't think it should rely on GlobalDebugLevel for one thing - if we
are going to control printing of messages at runtime then in my mind
this should be done via debugfs and pr_debug or similar - an in-kernel
mechanism rather than something driver-provided. Also, the example you
give of:

        u32 tmp;
        if (!rtw_read(&tmp))
                DBG("reg = %d\n", tmp);

Doesn't seem overly unclear to me if DBG was a pr_debug or similar,
but I get what you're saying about repetition. This is just a small
thing though, would be interested to see what others think. Many
thanks.

Regards,
Phil

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-23  0:12                 ` Phillip Potter
@ 2021-08-23  6:38                   ` Pavel Skripkin
  2021-08-23  6:44                   ` Pavel Skripkin
  1 sibling, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-23  6:38 UTC (permalink / raw)
  To: Phillip Potter
  Cc: Larry Finger, Greg KH, Michael Straube, Fabio M. De Francesco,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On 8/23/21 3:12 AM, Phillip Potter wrote:
> On Sun, 22 Aug 2021 at 15:35, Pavel Skripkin <paskripkin@gmail.com> wrote:
>>
>> Hi, Greg, Larry and Phillip!
>>
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>>
>> The first thing I noticed is *no one* was checking read operations result, but
>> it can fail and driver may start writing random stack values into registers. It
>> can cause driver misbehavior or device misbehavior.
>>
>> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
>> funtions return an error, when something went wrong with usb transfer.
>>
>> It helps callers to break/return earlier and don't write random values to
>> registers or to rely on random values.
>>
>> Why is this pacth series RFC?
>>   1. I don't have this device and I cannot test these changes.
>>   2. I don't know how to handle errors in each particular case. For now, function
>>      just returns or returns an error. That's all. I hope, driver maintainers will
>>      help with these bits.
>>   3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>>      at least half of them
>>
>>
>> v1 -> v2:
>>   1. Make rtw_read*() return an error instead of initializing pointer to error
>>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>>      changes
>>   3. Add new macro for printing register values (It helps to not copy-paste error
>>      handling)
>>   4. Removed {read,write}_macreg (Suggested by Phillip)
>>   5. Rebased on top of staging-next
>>   6. Cleaned checkpatch errors and warnings
>>
>> Only build-tested, since I don't have device with r8118eu chip
>>
>> Pavel Skripkin (6):
>>   staging: r8188eu: remove {read,write}_macreg
>>   staging: r8188eu: add helper macro for printing registers
>>   staging: r8188eu: add error handling of rtw_read8
>>   staging: r8188eu: add error handling of rtw_read16
>>   staging: r8188eu: add error handling of rtw_read32
>>   staging: r8188eu: make ReadEFuse return an int
>>
>>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>>  drivers/staging/r8188eu/core/rtw_efuse.c      | 125 +++--
>>  drivers/staging/r8188eu/core/rtw_io.c         |  27 +-
>>  drivers/staging/r8188eu/core/rtw_mp.c         |  70 ++-
>>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  13 +-
>>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   5 +-
>>  drivers/staging/r8188eu/core/rtw_sreset.c     |   9 +-
>>  .../r8188eu/hal/Hal8188ERateAdaptive.c        |   8 +-
>>  drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |  21 +-
>>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>>  drivers/staging/r8188eu/hal/hal_com.c         |  23 +-
>>  drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
>>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  33 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 285 +++++++++---
>>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  27 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  22 +-
>>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  18 +-
>>  drivers/staging/r8188eu/hal/usb_halinit.c     | 439 +++++++++++++++---
>>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  57 ++-
>>  drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
>>  .../staging/r8188eu/include/odm_interface.h   |   6 +-
>>  .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
>>  drivers/staging/r8188eu/include/rtw_debug.h   |  13 +
>>  drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
>>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>>  drivers/staging/r8188eu/include/rtw_mp.h      |   2 -
>>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 179 +++++--
>>  drivers/staging/r8188eu/os_dep/usb_intf.c     |   3 +-
>>  30 files changed, 1138 insertions(+), 389 deletions(-)
>>
>> --
>> 2.32.0
>>
> 
> Dear Pavel,
> 
> Thanks for this. I like the code a lot. One thing I am conflicted on
> is the helper macro for the printing of register values though. Whilst
> I'm not necessarily opposed to the concept of the macro itself, I
> don't think it should rely on GlobalDebugLevel for one thing - if we
> are going to control printing of messages at runtime then in my mind
> this should be done via debugfs and pr_debug or similar - an in-kernel
> mechanism rather than something driver-provided. Also, the example you

I've copy-pasted previous DBG() macro. I have a plan to clean up these 
debug macros in future, but I want to make these clean ups on top of 
this RFC to not rebase this huge patch set many times :)

> give of:
> 
>          u32 tmp;
>          if (!rtw_read(&tmp))
>                  DBG("reg = %d\n", tmp);
> 
> Doesn't seem overly unclear to me if DBG was a pr_debug or similar,
> but I get what you're saying about repetition. This is just a small
> thing though, would be interested to see what others think. Many
> thanks.
> 

To be honest, I made this macro, because I am lazy :P rtw_dbg_port() had 
a lot DBG_88E() calls with just register value, so I decided to wrap this.

I still believe, that this macro is useful, since callers won't care 
about creating temp variable and checking read() error code. This macro 
doesn't cover situation, where we want to print register + smth else, so 
if you have any idea about improvements, please, let me know :)


With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-23  0:12                 ` Phillip Potter
  2021-08-23  6:38                   ` Pavel Skripkin
@ 2021-08-23  6:44                   ` Pavel Skripkin
  1 sibling, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-23  6:44 UTC (permalink / raw)
  To: Phillip Potter
  Cc: Larry Finger, Greg KH, Michael Straube, Fabio M. De Francesco,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On 8/23/21 3:12 AM, Phillip Potter wrote:
> On Sun, 22 Aug 2021 at 15:35, Pavel Skripkin <paskripkin@gmail.com> wrote:
>>
>> Hi, Greg, Larry and Phillip!
>>
>> I noticed, that new staging driver was added like 3 weeks ago and I decided
>> to look at the code, because drivers in staging directory are always buggy.
>>
>> The first thing I noticed is *no one* was checking read operations result, but
>> it can fail and driver may start writing random stack values into registers. It
>> can cause driver misbehavior or device misbehavior.
>>
>> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
>> funtions return an error, when something went wrong with usb transfer.
>>
>> It helps callers to break/return earlier and don't write random values to
>> registers or to rely on random values.
>>
>> Why is this pacth series RFC?
>>   1. I don't have this device and I cannot test these changes.
>>   2. I don't know how to handle errors in each particular case. For now, function
>>      just returns or returns an error. That's all. I hope, driver maintainers will
>>      help with these bits.
>>   3. I guess, I handled not all uninit value bugs here. I hope, I fixed
>>      at least half of them
>>
>>
>> v1 -> v2:
>>   1. Make rtw_read*() return an error instead of initializing pointer to error
>>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>>      changes
>>   3. Add new macro for printing register values (It helps to not copy-paste error
>>      handling)
>>   4. Removed {read,write}_macreg (Suggested by Phillip)
>>   5. Rebased on top of staging-next
>>   6. Cleaned checkpatch errors and warnings
>>
>> Only build-tested, since I don't have device with r8118eu chip
>>
>> Pavel Skripkin (6):
>>   staging: r8188eu: remove {read,write}_macreg
>>   staging: r8188eu: add helper macro for printing registers
>>   staging: r8188eu: add error handling of rtw_read8
>>   staging: r8188eu: add error handling of rtw_read16
>>   staging: r8188eu: add error handling of rtw_read32
>>   staging: r8188eu: make ReadEFuse return an int
>>
>>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>>  drivers/staging/r8188eu/core/rtw_efuse.c      | 125 +++--
>>  drivers/staging/r8188eu/core/rtw_io.c         |  27 +-
>>  drivers/staging/r8188eu/core/rtw_mp.c         |  70 ++-
>>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  13 +-
>>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   5 +-
>>  drivers/staging/r8188eu/core/rtw_sreset.c     |   9 +-
>>  .../r8188eu/hal/Hal8188ERateAdaptive.c        |   8 +-
>>  drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |  21 +-
>>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>>  drivers/staging/r8188eu/hal/hal_com.c         |  23 +-
>>  drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
>>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  33 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 285 +++++++++---
>>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  27 +-
>>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  22 +-
>>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  18 +-
>>  drivers/staging/r8188eu/hal/usb_halinit.c     | 439 +++++++++++++++---
>>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  57 ++-
>>  drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
>>  .../staging/r8188eu/include/odm_interface.h   |   6 +-
>>  .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
>>  drivers/staging/r8188eu/include/rtw_debug.h   |  13 +
>>  drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
>>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>>  drivers/staging/r8188eu/include/rtw_mp.h      |   2 -
>>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 179 +++++--
>>  drivers/staging/r8188eu/os_dep/usb_intf.c     |   3 +-
>>  30 files changed, 1138 insertions(+), 389 deletions(-)
>>
>> --
>> 2.32.0
>>
> 
> Dear Pavel,
> 
> Thanks for this. I like the code a lot. One thing I am conflicted on
> is the helper macro for the printing of register values though. Whilst
> I'm not necessarily opposed to the concept of the macro itself, I
> don't think it should rely on GlobalDebugLevel for one thing - if we
> are going to control printing of messages at runtime then in my mind
> this should be done via debugfs and pr_debug or similar - an in-kernel
> mechanism rather than something driver-provided. Also, the example you
> give of:
> 
>          u32 tmp;
>          if (!rtw_read(&tmp))
>                  DBG("reg = %d\n", tmp);
> 
> Doesn't seem overly unclear to me if DBG was a pr_debug or similar,
> but I get what you're saying about repetition. This is just a small
> thing though, would be interested to see what others think. Many
> thanks.
> 

Btw, did you have a chance to test these changes? My r8188eu device 
_should_ come in few days, so I am not able to test it right now :)


With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-22 14:36                 ` [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32 Pavel Skripkin
@ 2021-08-23 23:33                   ` Phillip Potter
  2021-08-24  0:10                     ` Fabio M. De Francesco
                                       ` (2 more replies)
  2021-08-24  6:58                   ` [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32 Dan Carpenter
  1 sibling, 3 replies; 118+ messages in thread
From: Phillip Potter @ 2021-08-23 23:33 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry Finger, Greg KH, Michael Straube, Fabio M. De Francesco,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>  {
>         u8 requesttype;
>         u16 wvalue;
>         u16 len;
> -       __le32 data;
> +       int res;
> +       __le32 tmp;
> +
> +       if (WARN_ON(unlikely(!data)))
> +               return -EINVAL;
>
>         requesttype = 0x01;/* read_in */
>
>         wvalue = (u16)(addr & 0x0000ffff);
>         len = 4;
>
> -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> +       if (res < 0) {
> +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> +       } else {
> +               /* Noone cares about positive return value */
> +               *data = le32_to_cpu(tmp);
> +               res = 0;
> +       }
>
> -       return le32_to_cpu(data);
> +       return res;
>  }

Dear Pavel,

OK, found the issue with decoded stack trace after reviewing this
usb_read32 function. Your line:
res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);

should read:
res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);

With this change, the driver runs fine with no crashes/oopses. I will
explain the issue but you can probably see already, so I hope I'm not
coming across as patronising, just trying to be helpful :-)

Essentially, you are taking the address of the data function parameter
on this line with &data, a pointer to u32, which is giving you a
pointer to a pointer to u32 (u32 **) for this function parameter
variable. When passed to usbctrl_vendorreq, it is being passed to
memcpy inside this function as a void *, meaning that memcpy
subsequently overwrites the value of the memory address inside data to
point to a different location, which is problem when it is later
deferenced at:
*data = le32_to_cpu(tmp);
causing the OOPS

Also, as written, you can probably see that tmp is uninitialised. This
looks like a typo, so guessing this wasn't your intention. Anyhow,
with that small change, usbctrl_vendorreq reads into tmp, which is
then passed to le32_to_cpu whose return value is stored via the
deferenced data ptr (which now has its original address within and not
inadvertently modified). Hope this helps, and I'd be happy to Ack the
series if you want to resend this patch. Many thanks.

Regards,
Phil

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-23 23:33                   ` Phillip Potter
@ 2021-08-24  0:10                     ` Fabio M. De Francesco
  2021-08-24  6:40                       ` Pavel Skripkin
  2021-08-24  6:53                     ` Pavel Skripkin
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
  2 siblings, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-24  0:10 UTC (permalink / raw)
  To: Pavel Skripkin, Phillip Potter
  Cc: Larry Finger, Greg KH, Michael Straube,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >  {
> >         u8 requesttype;
> >         u16 wvalue;
> >         u16 len;
> > -       __le32 data;
> > +       int res;
> > +       __le32 tmp;
> > +
> > +       if (WARN_ON(unlikely(!data)))
> > +               return -EINVAL;
> >
> >         requesttype = 0x01;/* read_in */
> >
> >         wvalue = (u16)(addr & 0x0000ffff);
> >         len = 4;
> >
> > -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> > +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> > +       if (res < 0) {
> > +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> > +       } else {
> > +               /* Noone cares about positive return value */
> > +               *data = le32_to_cpu(tmp);
> > +               res = 0;
> > +       }
> >
> > -       return le32_to_cpu(data);
> > +       return res;
> >  }
> 
> Dear Pavel,
> 
> OK, found the issue with decoded stack trace after reviewing this
> usb_read32 function. Your line:
> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> 
> should read:
> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);

Dear Philip,

No, it should read:

res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);

I suspect that Pavel didn't notice he was reusing a line of the old code 
wth no due changes.

> With this change, the driver runs fine with no crashes/oopses. I will
> explain the issue but you can probably see already, so I hope I'm not
> coming across as patronising, just trying to be helpful :-)
> 
> Essentially, you are taking the address of the data function parameter
> on this line with &data, a pointer to u32, which is giving you a
> pointer to a pointer to u32 (u32 **) for this function parameter
> variable. When passed to usbctrl_vendorreq, it is being passed to
> memcpy inside this function as a void *, meaning that memcpy
> subsequently overwrites the value of the memory address inside data to
> point to a different location, which is problem when it is later
> deferenced at:
> *data = le32_to_cpu(tmp);
> causing the OOPS
> 
> Also, as written, you can probably see that tmp is uninitialised. This
> looks like a typo, so guessing this wasn't your intention. Anyhow,
> with that small change, usbctrl_vendorreq reads into tmp, which is
> then passed to le32_to_cpu whose return value is stored via the
> deferenced data ptr (which now has its original address within and not
> inadvertently modified). Hope this helps, and I'd be happy to Ack the
> series if you want to resend this patch. Many thanks.

I think that another typo is having 'tmp', because that variable is unnecessary
and "*data = le32_to_cpu(tmp);" is wrong too.

Now I also see that also usb_read16() is wrong, while usb_read8() (the one that 
I had read yesterday) is the only correct function of the three usb_read*().

Regards,

Fabio
> 
> Regards,
> Phil
> 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  0:10                     ` Fabio M. De Francesco
@ 2021-08-24  6:40                       ` Pavel Skripkin
  2021-08-24  8:38                         ` Fabio M. De Francesco
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  6:40 UTC (permalink / raw)
  To: Fabio M. De Francesco, Phillip Potter
  Cc: Larry Finger, Greg KH, Michael Straube,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
> On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
>> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
>> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>> >  {
>> >         u8 requesttype;
>> >         u16 wvalue;
>> >         u16 len;
>> > -       __le32 data;
>> > +       int res;
>> > +       __le32 tmp;
>> > +
>> > +       if (WARN_ON(unlikely(!data)))
>> > +               return -EINVAL;
>> >
>> >         requesttype = 0x01;/* read_in */
>> >
>> >         wvalue = (u16)(addr & 0x0000ffff);
>> >         len = 4;
>> >
>> > -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> > +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> > +       if (res < 0) {
>> > +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>> > +       } else {
>> > +               /* Noone cares about positive return value */
>> > +               *data = le32_to_cpu(tmp);
>> > +               res = 0;
>> > +       }
>> >
>> > -       return le32_to_cpu(data);
>> > +       return res;
>> >  }
>> 
>> Dear Pavel,
>> 
>> OK, found the issue with decoded stack trace after reviewing this
>> usb_read32 function. Your line:
>> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> 
>> should read:
>> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> 
> Dear Philip,
> 
> No, it should read:
> 
> res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
> 
> I suspect that Pavel didn't notice he was reusing a line of the old code
> wth no due changes.
> 
>> With this change, the driver runs fine with no crashes/oopses. I will
>> explain the issue but you can probably see already, so I hope I'm not
>> coming across as patronising, just trying to be helpful :-)
>> 
>> Essentially, you are taking the address of the data function parameter
>> on this line with &data, a pointer to u32, which is giving you a
>> pointer to a pointer to u32 (u32 **) for this function parameter
>> variable. When passed to usbctrl_vendorreq, it is being passed to
>> memcpy inside this function as a void *, meaning that memcpy
>> subsequently overwrites the value of the memory address inside data to
>> point to a different location, which is problem when it is later
>> deferenced at:
>> *data = le32_to_cpu(tmp);
>> causing the OOPS
>> 
>> Also, as written, you can probably see that tmp is uninitialised. This
>> looks like a typo, so guessing this wasn't your intention. Anyhow,
>> with that small change, usbctrl_vendorreq reads into tmp, which is
>> then passed to le32_to_cpu whose return value is stored via the
>> deferenced data ptr (which now has its original address within and not
>> inadvertently modified). Hope this helps, and I'd be happy to Ack the
>> series if you want to resend this patch. Many thanks.
> 
> I think that another typo is having 'tmp', because that variable is unnecessary
> and "*data = le32_to_cpu(tmp);" is wrong too.
> 
> Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
> I had read yesterday) is the only correct function of the three usb_read*().
> 

Hi, guys!


Sorry for breaking your system, Phillip. This code was part of "last 
minute" changes and yes, it's broken :)

I get what Phillip said, because I _should_ read into tmp variable 
instead of directly to data, but I don't get Fabio's idea, sorry.

Data from chip comes in little-endian, so we _should_ convert it to 
cpu's endian. Temp variable is needed to make smatch and all other 
static anylis tools happy about this code.


If I am missing something, please, let me know :) v3 is on the way...





With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-23 23:33                   ` Phillip Potter
  2021-08-24  0:10                     ` Fabio M. De Francesco
@ 2021-08-24  6:53                     ` Pavel Skripkin
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
  2 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  6:53 UTC (permalink / raw)
  To: Phillip Potter
  Cc: Larry Finger, Greg KH, Michael Straube, Fabio M. De Francesco,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On 8/24/21 2:33 AM, Phillip Potter wrote:
> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
>> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>>  {
>>         u8 requesttype;
>>         u16 wvalue;
>>         u16 len;
>> -       __le32 data;
>> +       int res;
>> +       __le32 tmp;
>> +
>> +       if (WARN_ON(unlikely(!data)))
>> +               return -EINVAL;
>>
>>         requesttype = 0x01;/* read_in */
>>
>>         wvalue = (u16)(addr & 0x0000ffff);
>>         len = 4;
>>
>> -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> +       if (res < 0) {
>> +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>> +       } else {
>> +               /* Noone cares about positive return value */
>> +               *data = le32_to_cpu(tmp);
>> +               res = 0;
>> +       }
>>
>> -       return le32_to_cpu(data);
>> +       return res;
>>  }
> 
> Dear Pavel,
> 
> OK, found the issue with decoded stack trace after reviewing this
> usb_read32 function. Your line:
> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> 
> should read:
> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> 
> With this change, the driver runs fine with no crashes/oopses. I will
> explain the issue but you can probably see already, so I hope I'm not
> coming across as patronising, just trying to be helpful :-)
> 
> Essentially, you are taking the address of the data function parameter
> on this line with &data, a pointer to u32, which is giving you a
> pointer to a pointer to u32 (u32 **) for this function parameter
> variable. When passed to usbctrl_vendorreq, it is being passed to
> memcpy inside this function as a void *, meaning that memcpy
> subsequently overwrites the value of the memory address inside data to
> point to a different location, which is problem when it is later
> deferenced at:
> *data = le32_to_cpu(tmp);
> causing the OOPS
> 

The most strange thing is why gcc didn't complain about different 
pointer types... I think, that gcc must complain about this type of not 
explicit casts, because 99% it's a bug.


Again big thanks for analysis :)



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-22 14:36                 ` [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32 Pavel Skripkin
  2021-08-23 23:33                   ` Phillip Potter
@ 2021-08-24  6:58                   ` Dan Carpenter
  2021-08-24  7:01                     ` Pavel Skripkin
  1 sibling, 1 reply; 118+ messages in thread
From: Dan Carpenter @ 2021-08-24  6:58 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On Sun, Aug 22, 2021 at 05:36:01PM +0300, Pavel Skripkin wrote:
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>  {
>  	u8 requesttype;
>  	u16 wvalue;
>  	u16 len;
> -	__le32 data;
> +	int res;
> +	__le32 tmp;
> +
> +	if (WARN_ON(unlikely(!data)))
> +		return -EINVAL;
>  
>  	requesttype = 0x01;/* read_in */
>  
>  	wvalue = (u16)(addr & 0x0000ffff);
>  	len = 4;
>  
> -	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> +	res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> +	if (res < 0) {
> +		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);

Add a return here.  Try to keep the success path and the failure path
as separate as possible.  Try to keep the success path indented at one
tab so the code looks like this:

	success();
	success();
	if (fail)
		handle_failure();
	success();
	success();

Try to deal with exceptions as quickly as possible so that the reader
has less to remember.

> +	} else {
> +		/* Noone cares about positive return value */

Ugh...  That's unfortunate.  We should actually care.  The
usbctrl_vendorreq() has an information leak where it copies len (4)
bytes of data even if usb_control_msg() is not able to read len bytes.

The best fix would be to remove the information leak and make
usbctrl_vendorreq() return zero on success.  In other words something
like:

	status = usb_control_msg();
	if (status < 0)
		return status;
	if (status != len)
		return -EIO;
	status = 0;

> +		*data = le32_to_cpu(tmp);
> +		res = 0;
> +	}
>  
> -	return le32_to_cpu(data);
> +	return res;
>  }


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  6:58                   ` [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32 Dan Carpenter
@ 2021-08-24  7:01                     ` Pavel Skripkin
  2021-08-24 15:07                       ` Fabio M. De Francesco
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  7:01 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On 8/24/21 9:58 AM, Dan Carpenter wrote:
> On Sun, Aug 22, 2021 at 05:36:01PM +0300, Pavel Skripkin wrote:
>> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>>  {
>>  	u8 requesttype;
>>  	u16 wvalue;
>>  	u16 len;
>> -	__le32 data;
>> +	int res;
>> +	__le32 tmp;
>> +
>> +	if (WARN_ON(unlikely(!data)))
>> +		return -EINVAL;
>>  
>>  	requesttype = 0x01;/* read_in */
>>  
>>  	wvalue = (u16)(addr & 0x0000ffff);
>>  	len = 4;
>>  
>> -	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> +	res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> +	if (res < 0) {
>> +		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> 
> Add a return here.  Try to keep the success path and the failure path
> as separate as possible.  Try to keep the success path indented at one
> tab so the code looks like this:
> 
> 	success();
> 	success();
> 	if (fail)
> 		handle_failure();
> 	success();
> 	success();
> 
> Try to deal with exceptions as quickly as possible so that the reader
> has less to remember.
> 
>> +	} else {
>> +		/* Noone cares about positive return value */
> 
> Ugh...  That's unfortunate.  We should actually care.  The
> usbctrl_vendorreq() has an information leak where it copies len (4)
> bytes of data even if usb_control_msg() is not able to read len bytes.
> 
> The best fix would be to remove the information leak and make
> usbctrl_vendorreq() return zero on success.  In other words something
> like:
> 
> 	status = usb_control_msg();
> 	if (status < 0)
> 		return status;
> 	if (status != len)
> 		return -EIO;
> 	status = 0;
> 

I see, thank you for reviewing, will fix in v3! I fully forgot, that 
usb_control_msg() can receive only part of the message :)



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-23 23:33                   ` Phillip Potter
  2021-08-24  0:10                     ` Fabio M. De Francesco
  2021-08-24  6:53                     ` Pavel Skripkin
@ 2021-08-24  7:25                     ` Pavel Skripkin
  2021-08-24  7:27                       ` [PATCH v3 1/6] staging: r8188eu: remove {read,write}_macreg Pavel Skripkin
                                         ` (7 more replies)
  2 siblings, 8 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  7:25 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

Hi, Greg, Larry and Phillip!

I noticed, that new staging driver was added like 3 weeks ago and I decided
to look at the code, because drivers in staging directory are always buggy.

The first thing I noticed is *no one* was checking read operations result, but
it can fail and driver may start writing random stack values into registers. It
can cause driver misbehavior or device misbehavior.

To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
funtions return an error, when something went wrong with usb transfer.

It helps callers to break/return earlier and don't write random values to
registers or to rely on random values.


v2 -> v3:
  1. Fixed OOPS in usb_read32(), caused by writing to u32 **
  2. Fixed style in rtw_read32, rtw_read16 and rtw_read8 (Suggested by Dan)
  3. Added error hanling when usb_control_msg() returns ret != len
     NOTE: Dan suggested to add this to usbctrl_vendorreq(), but there is
     pending series, which will get rid of usb_control_msg(), so (res != len)
     check can be removed, when Fabio's series will go in
  4. Removed RFC tag

v1 -> v2:
  1. Make rtw_read*() return an error instead of initializing pointer to error
  2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
     changes
  3. Add new macro for printing register values (It helps to not copy-paste error
     handling)
  4. Removed {read,write}_macreg (Suggested by Phillip)
  5. Rebased on top of staging-next
  6. Cleaned checkpatch errors and warnings


Phillip has tested fixed v2 version, AFAIU

Pavel Skripkin (6):
  staging: r8188eu: remove {read,write}_macreg
  staging: r8188eu: add helper macro for printing registers
  staging: r8188eu: add error handling of rtw_read8
  staging: r8188eu: add error handling of rtw_read16
  staging: r8188eu: add error handling of rtw_read32
  staging: r8188eu: make ReadEFuse return an int

 drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
 drivers/staging/r8188eu/core/rtw_efuse.c      | 125 +++--
 drivers/staging/r8188eu/core/rtw_io.c         |  27 +-
 drivers/staging/r8188eu/core/rtw_mp.c         |  70 ++-
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  13 +-
 drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   5 +-
 drivers/staging/r8188eu/core/rtw_sreset.c     |   9 +-
 .../r8188eu/hal/Hal8188ERateAdaptive.c        |   8 +-
 drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |  21 +-
 drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
 drivers/staging/r8188eu/hal/hal_com.c         |  23 +-
 drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
 drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  33 +-
 drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 285 +++++++++---
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  27 +-
 drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  22 +-
 drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  18 +-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 439 +++++++++++++++---
 drivers/staging/r8188eu/hal/usb_ops_linux.c   |  62 ++-
 drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
 .../staging/r8188eu/include/odm_interface.h   |   6 +-
 .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
 drivers/staging/r8188eu/include/rtw_debug.h   |  13 +
 drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
 drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
 drivers/staging/r8188eu/include/rtw_mp.h      |   2 -
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 179 +++++--
 drivers/staging/r8188eu/os_dep/usb_intf.c     |   3 +-
 30 files changed, 1143 insertions(+), 389 deletions(-)

-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v3 1/6] staging: r8188eu: remove {read,write}_macreg
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
@ 2021-08-24  7:27                       ` Pavel Skripkin
  2021-08-26 10:39                         ` Greg KH
  2021-08-26 10:40                         ` Greg KH
  2021-08-24  7:27                       ` [PATCH v3 2/6] staging: r8188eu: add helper macro for printing registers Pavel Skripkin
                                         ` (6 subsequent siblings)
  7 siblings, 2 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  7:27 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

These 2 functions are unused, so they can be simply removed

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_mp.c    | 39 ------------------------
 drivers/staging/r8188eu/include/rtw_mp.h |  2 --
 2 files changed, 41 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 93bb683b628f..0a0a24fd37b0 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -7,45 +7,6 @@
 #include "../include/odm_precomp.h"
 #include "../include/rtl8188e_hal.h"
 
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz)
-{
-	u32 val = 0;
-
-	switch (sz) {
-	case 1:
-		val = rtw_read8(padapter, addr);
-		break;
-	case 2:
-		val = rtw_read16(padapter, addr);
-		break;
-	case 4:
-		val = rtw_read32(padapter, addr);
-		break;
-	default:
-		val = 0xffffffff;
-		break;
-	}
-
-	return val;
-}
-
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz)
-{
-	switch (sz) {
-	case 1:
-		rtw_write8(padapter, addr, (u8)val);
-		break;
-	case 2:
-		rtw_write16(padapter, addr, (u16)val);
-		break;
-	case 4:
-		rtw_write32(padapter, addr, val);
-		break;
-	default:
-		break;
-	}
-}
-
 u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask)
 {
 	return rtw_hal_read_bbreg(padapter, addr, bitmask);
diff --git a/drivers/staging/r8188eu/include/rtw_mp.h b/drivers/staging/r8188eu/include/rtw_mp.h
index b64b16554343..3a259d991348 100644
--- a/drivers/staging/r8188eu/include/rtw_mp.h
+++ b/drivers/staging/r8188eu/include/rtw_mp.h
@@ -410,8 +410,6 @@ void mp_stop_test(struct adapter *padapter);
 u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask);
 void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val);
 
-u32 read_macreg(struct adapter *padapter, u32 addr, u32 sz);
-void write_macreg(struct adapter *padapter, u32 addr, u32 val, u32 sz);
 u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask);
 void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val);
 u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr);
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v3 2/6] staging: r8188eu: add helper macro for printing registers
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
  2021-08-24  7:27                       ` [PATCH v3 1/6] staging: r8188eu: remove {read,write}_macreg Pavel Skripkin
@ 2021-08-24  7:27                       ` Pavel Skripkin
  2021-08-26 10:37                         ` Greg KH
  2021-08-24  7:27                       ` [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8 Pavel Skripkin
                                         ` (5 subsequent siblings)
  7 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  7:27 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

There are a lof of places, where DBG_88E() is used to print register
value. Since following patches change _rtw_read*() family
prototypes, we can wrap printing registers into useful macro to avoid
open-coding error checking like this:

	u32 tmp;
	if (!rtw_read(&tmp))
		DBG("reg = %d\n", tmp);

So, added DBG_88E_REG{8,16,32} macros for printing register values.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/include/rtw_debug.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/staging/r8188eu/include/rtw_debug.h b/drivers/staging/r8188eu/include/rtw_debug.h
index 3c3bf2a4f30e..059647b9cd3a 100644
--- a/drivers/staging/r8188eu/include/rtw_debug.h
+++ b/drivers/staging/r8188eu/include/rtw_debug.h
@@ -72,6 +72,19 @@ extern u32 GlobalDebugLevel;
 			pr_info(DRIVER_PREFIX __VA_ARGS__);			\
 	} while (0)
 
+#define __DBG_88E_REG(fmt, adap, reg, size)				\
+	do {								\
+		u##size __tmp__;					\
+		if (rtw_read##size((adap), (reg), &__tmp__))		\
+			break;						\
+		if (_drv_err_ <= GlobalDebugLevel)			\
+			pr_info(DRIVER_PREFIX fmt, __tmp__);		\
+	} while (0)
+
+#define DBG_88E_REG8(fmt, adap, reg)	__DBG_88E_REG(fmt, adap, reg, 8)
+#define DBG_88E_REG16(fmt, adap, reg)	__DBG_88E_REG(fmt, adap, reg, 16)
+#define DBG_88E_REG32(fmt, adap, reg)	__DBG_88E_REG(fmt, adap, reg, 32)
+
 int proc_get_drv_version(char *page, char **start,
 			 off_t offset, int count,
 			 int *eof, void *data);
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
  2021-08-24  7:27                       ` [PATCH v3 1/6] staging: r8188eu: remove {read,write}_macreg Pavel Skripkin
  2021-08-24  7:27                       ` [PATCH v3 2/6] staging: r8188eu: add helper macro for printing registers Pavel Skripkin
@ 2021-08-24  7:27                       ` Pavel Skripkin
  2021-08-25 12:05                         ` kernel test robot
                                           ` (4 more replies)
  2021-08-24  7:27                       ` [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16 Pavel Skripkin
                                         ` (4 subsequent siblings)
  7 siblings, 5 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  7:27 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

_rtw_read8 function can fail in case of usb transfer failure. But
previous function prototype wasn't designed to return an error to
caller. It can cause a lot uninit value bugs all across the driver code,
since rtw_read8() returns local stack variable to caller.

Fix it by changing the prototype of this function. Now it returns an
int: 0 on success, negative error value on failure and callers should pass
the pointer to storage location for register value.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_debug.c      |  11 +-
 drivers/staging/r8188eu/core/rtw_efuse.c      |  76 +++--
 drivers/staging/r8188eu/core/rtw_io.c         |   9 +-
 drivers/staging/r8188eu/core/rtw_mp.c         |  13 +-
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |   5 +-
 drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |  19 +-
 drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
 drivers/staging/r8188eu/hal/hal_com.c         |  23 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |   4 +-
 drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  33 ++-
 drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 128 +++++++--
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  10 +-
 drivers/staging/r8188eu/hal/rtl8188e_sreset.c |   8 +-
 drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  18 +-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 267 +++++++++++++++---
 drivers/staging/r8188eu/hal/usb_ops_linux.c   |  18 +-
 .../staging/r8188eu/include/odm_interface.h   |   2 +-
 drivers/staging/r8188eu/include/rtw_io.h      |   6 +-
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  |  61 +++-
 20 files changed, 568 insertions(+), 158 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 2ee64cef73f7..8b7d3eb12bd0 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -73,8 +73,8 @@ int proc_get_read_reg(char *page, char **start,
 {
 	struct net_device *dev = data;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
-
-	int len = 0;
+	u32 tmp;
+	int len = 0, error;
 
 	if (proc_get_read_addr == 0xeeeeeeee) {
 		*eof = 1;
@@ -83,7 +83,12 @@ int proc_get_read_reg(char *page, char **start,
 
 	switch (proc_get_read_len) {
 	case 1:
-		len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr));
+		error = rtw_read8(padapter, proc_get_read_addr, (u8 *) &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n",
+				proc_get_read_addr, (u8) tmp);
 		break;
 	case 2:
 		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index decccf7622f0..b471f6446f78 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -159,6 +159,7 @@ ReadEFuseByte(
 	u32 value32;
 	u8 readbyte;
 	u16 retry;
+	int error;
 
 	if (pseudo) {
 		Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
@@ -167,11 +168,17 @@ ReadEFuseByte(
 
 	/* Write Address */
 	rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
-	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 2);
+	error = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
 
 	/* Write bit 32 0 */
-	readbyte = rtw_read8(Adapter, EFUSE_CTRL + 3);
+	error = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
 
 	/* Check bit 32 read-ready */
@@ -244,6 +251,7 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
 	u8 temp = {0x00};
 	u32 k = 0;
 	u16 contentLen = 0;
+	int error;
 
 	EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
 
@@ -251,27 +259,42 @@ u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address)
 		/* Write E-fuse Register address bit0~7 */
 		temp = Address & 0xFF;
 		rtw_write8(Adapter, EFUSE_CTRL + 1, temp);
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2);
+		error = rtw_read8(Adapter, EFUSE_CTRL + 2, &Bytetemp);
+		if (error)
+			return 0xFF;
+
 		/* Write E-fuse Register address bit8~9 */
 		temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
 		rtw_write8(Adapter, EFUSE_CTRL + 2, temp);
 
 		/* Write 0x30[31]= 0 */
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+		error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
+		if (error)
+			return 0xFF;
+
 		temp = Bytetemp & 0x7F;
 		rtw_write8(Adapter, EFUSE_CTRL + 3, temp);
 
 		/* Wait Write-ready (0x30[31]= 1) */
-		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+		error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
+		if (error)
+			return 0xFF;
+
 		while (!(Bytetemp & 0x80)) {
-			Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
+			error = rtw_read8(Adapter, EFUSE_CTRL + 3, &Bytetemp);
+			if (error)
+				return 0xFF;
+
 			k++;
 			if (k == 1000) {
 				k = 0;
 				break;
 			}
 		}
-		data = rtw_read8(Adapter, EFUSE_CTRL);
+		error = rtw_read8(Adapter, EFUSE_CTRL, &data);
+		if (error)
+			return 0xFF;
+
 		return data;
 	} else {
 		return 0xFF;
@@ -284,6 +307,8 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
 {
 	u8 tmpidx = 0;
 	u8 result;
+	u8 tmp;
+	int error;
 
 	if (pseudo) {
 		result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
@@ -292,16 +317,25 @@ u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo)
 	/*  -----------------e-fuse reg ctrl --------------------------------- */
 	/* address */
 	rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
-	rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
-		   (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
+	error = rtw_read8(pAdapter, EFUSE_CTRL + 2, &tmp);
+	if (error)
+		return false;
 
+	rtw_write8(pAdapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) | (tmp & 0xFC));
 	rtw_write8(pAdapter, EFUSE_CTRL + 3,  0x72);/* read cmd */
 
-	while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
-		tmpidx++;
+	do {
+		error = rtw_read8(pAdapter, EFUSE_CTRL + 3, &tmp);
+		if (error)
+			return false;
+	} while (!(0x80 & tmp) && (++tmpidx < 100));
+
 	if (tmpidx < 100) {
-		*data = rtw_read8(pAdapter, EFUSE_CTRL);
-		result = true;
+		error = rtw_read8(pAdapter, EFUSE_CTRL, data);
+		if (error)
+			result = false;
+		else
+			result = true;
 	} else {
 		*data = 0xff;
 		result = false;
@@ -314,6 +348,8 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
 {
 	u8 tmpidx = 0;
 	u8 result;
+	u8 tmp;
+	int error;
 
 	if (pseudo) {
 		result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
@@ -323,15 +359,23 @@ u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo)
 	/*  -----------------e-fuse reg ctrl --------------------------------- */
 	/* address */
 	rtw_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
+
+	error = rtw_read8(pAdapter, EFUSE_CTRL + 2, &tmp);
+	if (error)
+		return false;
+
 	rtw_write8(pAdapter, EFUSE_CTRL + 2,
-		   (rtw_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) |
+		   (tmp & 0xFC) |
 		   (u8)((addr >> 8) & 0x03));
 	rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */
 
 	rtw_write8(pAdapter, EFUSE_CTRL + 3, 0xF2);/* write cmd */
 
-	while ((0x80 &  rtw_read8(pAdapter, EFUSE_CTRL + 3)) && (tmpidx < 100))
-		tmpidx++;
+	do {
+		error = rtw_read8(pAdapter, EFUSE_CTRL + 3, &tmp);
+		if (error)
+			return false;
+	} while (!(0x80 & tmp) && (++tmpidx < 100));
 
 	if (tmpidx < 100)
 		result = true;
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index cde0205816b1..2714506c8ffb 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -34,18 +34,15 @@ jackson@realtek.com.tw
 #define rtw_cpu_to_le16(val)		cpu_to_le16(val)
 #define rtw_cpu_to_le32(val)		cpu_to_le32(val)
 
-u8 _rtw_read8(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
 {
-	u8 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl *pintfhdl = &pio_priv->intf;
-	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
-
+	int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
 
 	_read8 = pintfhdl->io_ops._read8;
-	r_val = _read8(pintfhdl, addr);
 
-	return r_val;
+	return _read8(pintfhdl, addr, data);
 }
 
 u16 _rtw_read16(struct adapter *adapter, u32 addr)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 0a0a24fd37b0..76f0bc399819 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -243,10 +243,14 @@ void GetPowerTracking(struct adapter *padapter, u8 *enable)
 static void disable_dm(struct adapter *padapter)
 {
 	u8 v8;
+	int error;
 
 	/* 3 1. disable firmware dynamic mechanism */
 	/*  disable Power Training, Rate Adaptive */
-	v8 = rtw_read8(padapter, REG_BCN_CTRL);
+	error = rtw_read8(padapter, REG_BCN_CTRL, &v8);
+	if (error)
+		return;
+
 	v8 &= ~EN_BCN_FUNCTION;
 	rtw_write8(padapter, REG_BCN_CTRL, v8);
 
@@ -363,8 +367,13 @@ s32 mp_start_test(struct adapter *padapter)
 	spin_unlock_bh(&pmlmepriv->lock);
 
 	if (res == _SUCCESS) {
+		int error;
 		/*  set MSR to WIFI_FW_ADHOC_STATE */
-		val8 = rtw_read8(padapter, MSR) & 0xFC; /*  0x0102 */
+		error = rtw_read8(padapter, MSR, &val8); /*  0x0102 */
+		if (error)
+			return _FAIL;
+
+		val8 &= 0xFC;
 		val8 |= WIFI_FW_ADHOC_STATE;
 		rtw_write8(padapter, MSR, val8); /*  Link in ad hoc network */
 	}
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c85f8e467337..894ab456f202 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -632,6 +632,7 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 	u32		offset, width;
 	int status = NDIS_STATUS_SUCCESS;
 	struct adapter *Adapter = (struct adapter *)(poid_par_priv->adapter_context);
+	int error;
 
 	if (poid_par_priv->type_of_oid != QUERY_OID)
 		return NDIS_STATUS_NOT_ACCEPTED;
@@ -647,7 +648,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 
 	switch (width) {
 	case 1:
-		RegRWStruct->value = rtw_read8(Adapter, offset);
+		error = rtw_read8(Adapter, offset, (u8 *) &RegRWStruct->value);
+		if (error)
+			status = NDIS_STATUS_NOT_ACCEPTED;
 		break;
 	case 2:
 		RegRWStruct->value = rtw_read16(Adapter, offset);
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index 356885e27edd..3545ad60dc00 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -660,8 +660,12 @@ static void _PHY_SaveMACRegisters(
 	u32 i;
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(adapt);
 	struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
+	int error;
+
 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) {
-		MACBackup[i] = ODM_Read1Byte(dm_odm, MACReg[i]);
+		error = ODM_Read1Byte(dm_odm, MACReg[i], (u8 *) &MACBackup[i]);
+		if (error)
+			return;
 	}
 	MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
 }
@@ -1010,9 +1014,12 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
 	u32 RF_Amode = 0, RF_Bmode = 0, LC_Cal;
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(adapt);
 	struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
+	int error;
 
 	/* Check continuous TX and Packet TX */
-	tmpreg = ODM_Read1Byte(dm_odm, 0xd03);
+	error = ODM_Read1Byte(dm_odm, 0xd03, &tmpreg);
+	if (error)
+		return;
 
 	if ((tmpreg & 0x70) != 0)			/* Deal with contisuous TX case */
 		ODM_Write1Byte(dm_odm, 0xd03, tmpreg & 0x8F);	/* disable all continuous TX */
@@ -1232,7 +1239,13 @@ static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2
 
 	if (!adapt->hw_init_completed) {
 		u8 u1btmp;
-		u1btmp = ODM_Read1Byte(dm_odm, REG_LEDCFG2) | BIT(7);
+		int error;
+
+		error = ODM_Read1Byte(dm_odm, REG_LEDCFG2, &u1btmp);
+		if (error)
+			return;
+
+		u1btmp |= BIT(7);
 		ODM_Write1Byte(dm_odm, REG_LEDCFG2, u1btmp);
 		ODM_SetBBReg(dm_odm, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
 	}
diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
index 0fd11aca7ac7..74e83381ef06 100644
--- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c
@@ -35,6 +35,7 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 	u32 offset = 0;
 	u32 poll_count = 0; /*  polling autoload done. */
 	u32 max_poll_count = 5000;
+	int error;
 
 	do {
 		pwrcfgcmd = pwrseqcmd[aryidx];
@@ -48,7 +49,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
 
 				/*  Read the value from system register */
-				value = rtw_read8(padapter, offset);
+				error = rtw_read8(padapter, offset, &value);
+				if (error)
+					return false;
 
 				value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
 				value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
@@ -60,7 +63,9 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
 				poll_bit = false;
 				offset = GET_PWR_CFG_OFFSET(pwrcfgcmd);
 				do {
-					value = rtw_read8(padapter, offset);
+					error = rtw_read8(padapter, offset, &value);
+					if (error)
+						return false;
 
 					value &= GET_PWR_CFG_MASK(pwrcfgcmd);
 					if (value == (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd)))
diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c
index f09d4d49b159..833c88c85e3f 100644
--- a/drivers/staging/r8188eu/hal/hal_com.c
+++ b/drivers/staging/r8188eu/hal/hal_com.c
@@ -321,11 +321,14 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
 	struct c2h_evt_hdr *c2h_evt;
 	int i;
 	u8 trigger;
+	int error;
 
 	if (!buf)
 		goto exit;
 
-	trigger = rtw_read8(adapter, REG_C2HEVT_CLEAR);
+	error = rtw_read8(adapter, REG_C2HEVT_CLEAR, &trigger);
+	if (error)
+		goto exit;
 
 	if (trigger == C2H_EVT_HOST_CLOSE)
 		goto exit; /* Not ready */
@@ -336,13 +339,21 @@ s32 c2h_evt_read(struct adapter *adapter, u8 *buf)
 
 	memset(c2h_evt, 0, 16);
 
-	*buf = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL);
-	*(buf + 1) = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
+	error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, buf);
+	if (error)
+		goto clear_evt;
+
+	error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, buf + 1);
+	if (error)
+		goto clear_evt;
 
 	/* Read the content */
-	for (i = 0; i < c2h_evt->plen; i++)
-		c2h_evt->payload[i] = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL +
-						sizeof(*c2h_evt) + i);
+	for (i = 0; i < c2h_evt->plen; i++) {
+		error = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + sizeof(*c2h_evt) + i,
+				  c2h_evt->payload + i);
+		if (error)
+			goto clear_evt;
+	}
 
 	ret = _SUCCESS;
 
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 5a01495d74bc..9a9df98da727 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -4,10 +4,10 @@
 #include "../include/odm_precomp.h"
 /*  ODM IO Relative API. */
 
-u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read8(Adapter, RegAddr);
+	return rtw_read8(Adapter, RegAddr, data);
 }
 
 u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
index 3e1a45030bc8..53636c0e4786 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c
@@ -21,12 +21,14 @@ static u8 _is_fw_read_cmd_down(struct adapter *adapt, u8 msgbox_num)
 {
 	u8 read_down = false;
 	int	retry_cnts = 100;
-
+	int error;
 	u8 valid;
 
 	do {
-		valid = rtw_read8(adapt, REG_HMETFR) & BIT(msgbox_num);
-		if (0 == valid)
+		error = rtw_read8(adapt, REG_HMETFR, &valid);
+		if (error)
+			return read_down;
+		else if (!(valid & BIT(msgbox_num)))
 			read_down = true;
 	} while ((!read_down) && (retry_cnts--));
 
@@ -578,8 +580,9 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
 	bool	bSendBeacon = false;
 	bool	bcn_valid = false;
-	u8 DLBcnCount = 0;
+	u8 DLBcnCount = 0, val8;
 	u32 poll = 0;
+	int error;
 
 	DBG_88E("%s mstatus(%x)\n", __func__, mstatus);
 
@@ -596,8 +599,15 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 		/*  Disable Hw protection for a time which revserd for Hw sending beacon. */
 		/*  Fix download reserved page packet fail that access collision with the protection time. */
 		/*  2010.05.11. Added by tynli. */
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(3)));
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(4));
+		error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+		if (error)
+			return;
+		rtw_write8(adapt, REG_BCN_CTRL, val8 & (~BIT(3)));
+
+		error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+		if (error)
+			return;
+		rtw_write8(adapt, REG_BCN_CTRL, val8 | BIT(4));
 
 		if (haldata->RegFwHwTxQCtrl & BIT(6)) {
 			DBG_88E("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
@@ -639,8 +649,15 @@ void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *adapt, u8 mstatus)
 		/*  */
 
 		/*  Enable Bcn */
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) | BIT(3));
-		rtw_write8(adapt, REG_BCN_CTRL, rtw_read8(adapt, REG_BCN_CTRL) & (~BIT(4)));
+		error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+		if (error)
+			return;
+		rtw_write8(adapt, REG_BCN_CTRL, val8 | BIT(3));
+
+		error = rtw_read8(adapt, REG_BCN_CTRL, &val8);
+		if (error)
+			return;
+		rtw_write8(adapt, REG_BCN_CTRL, val8 & (~BIT(4)));
 
 		/*  To make sure that if there exists an adapter which would like to send beacon. */
 		/*  If exists, the origianl value of 0x422[6] will be 1, we should check this to */
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
index 78552303c990..5cb3d6369449 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_dm.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_dm.c
@@ -16,8 +16,12 @@ static void dm_CheckStatistics(struct adapter *Adapter)
 static void dm_InitGPIOSetting(struct adapter *Adapter)
 {
 	u8	tmp1byte;
+	int error;
+
+	error = rtw_read8(Adapter, REG_GPIO_MUXCFG, &tmp1byte);
+	if (error)
+		return;
 
-	tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
 	tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
 
 	rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 393969f51206..cfc429965b7d 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -13,10 +13,14 @@
 static void iol_mode_enable(struct adapter *padapter, u8 enable)
 {
 	u8 reg_0xf0 = 0;
+	int error;
 
 	if (enable) {
 		/* Enable initial offload */
-		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+		error = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
 
 		if (!padapter->bFWReady) {
@@ -26,7 +30,10 @@ static void iol_mode_enable(struct adapter *padapter, u8 enable)
 
 	} else {
 		/* disable initial offload */
-		reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
+		error = rtw_read8(padapter, REG_SYS_CFG, &reg_0xf0);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
 	}
 }
@@ -35,19 +42,28 @@ static s32 iol_execute(struct adapter *padapter, u8 control)
 {
 	s32 status = _FAIL;
 	u8 reg_0x88 = 0;
-	u32 start = 0, passing_time = 0;
+	u32 start = 0;
+	int error;
 
 	control = control & 0x0f;
-	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+	error = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+	if (error)
+		return status;
+
 	rtw_write8(padapter, REG_HMEBOX_E0,  reg_0x88 | control);
 
 	start = jiffies;
-	while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
-	       (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
-		;
-	}
 
-	reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
+	do {
+		error = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+		if (error)
+			return status;
+	} while (reg_0x88 & control && rtw_get_passing_time_ms(start) < 1000);
+
+	error = rtw_read8(padapter, REG_HMEBOX_E0, &reg_0x88);
+	if (error)
+		return status;
+
 	status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
 	if (reg_0x88 & control << 4)
 		status = _FAIL;
@@ -195,17 +211,20 @@ static void efuse_read_phymap_from_txpktbuf(
 	)
 {
 	u16 dbg_addr = 0;
-	u32 start  = 0, passing_time = 0;
+	u32 start  = 0;
 	u8 reg_0x143 = 0;
 	__le32 lo32 = 0, hi32 = 0;
 	u16 len = 0, count = 0;
 	int i = 0;
 	u16 limit = *size;
-
+	int error;
 	u8 *pos = content;
 
-	if (bcnhead < 0) /* if not valid */
-		bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
+	if (bcnhead < 0) { /* if not valid */
+		error = rtw_read8(adapter, REG_TDECTRL + 1, (u8 *) &bcnhead);
+		if (error)
+			return;
+	}
 
 	DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
 
@@ -218,11 +237,21 @@ static void efuse_read_phymap_from_txpktbuf(
 
 		rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
 		start = jiffies;
-		while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
-		       (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
-			DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
+
+		do {
+			u8 tmp;
+
+			error = rtw_read8(adapter, REG_TXPKTBUF_DBG, &reg_0x143);
+			if (error)
+				return;
+
+			if (!rtw_read8(adapter, 0x106, &tmp))
+				DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n",
+					__func__, reg_0x143, tmp);
+
 			rtw_usleep_os(100);
-		}
+		} while (!reg_0x143 && rtw_get_passing_time_ms(start) < 1000);
+
 
 		/* data from EEPROM needs to be in LE */
 		lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
@@ -371,18 +400,28 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 static void _FWDownloadEnable(struct adapter *padapter, bool enable)
 {
 	u8 tmp;
+	int error;
 
 	if (enable) {
 		/*  MCU firmware download enable. */
-		tmp = rtw_read8(padapter, REG_MCUFWDL);
+		error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
 
 		/*  8051 reset */
-		tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
+		error = rtw_read8(padapter, REG_MCUFWDL + 2, &tmp);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
 	} else {
 		/*  MCU firmware download disable. */
-		tmp = rtw_read8(padapter, REG_MCUFWDL);
+		error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+		if (error)
+			return;
+
 		rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
 
 		/*  Reserved for fw extension. */
@@ -452,8 +491,14 @@ static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size
 {
 	u8 value8;
 	u8 u8Page = (u8)(page & 0x07);
+	int error;
 
-	value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
+	error = rtw_read8(padapter, REG_MCUFWDL + 2, &value8);
+	if (error)
+		return error;
+
+	value8 &= 0xF8;
+	value8 |= u8Page;
 	rtw_write8(padapter, REG_MCUFWDL + 2, value8);
 
 	return _BlockWrite(padapter, buffer, size);
@@ -493,8 +538,12 @@ static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
 void _8051Reset88E(struct adapter *padapter)
 {
 	u8 u1bTmp;
+	int error;
+
+	error = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &u1bTmp);
+	if (error)
+		return;
 
-	u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
 	rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2)));
 	rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2)));
 	DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
@@ -582,7 +631,7 @@ static int load_firmware(struct rt_firmware *pFirmware, struct device *device)
 s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 {
 	s32	rtStatus = _SUCCESS;
-	u8 writeFW_retry = 0;
+	u8 writeFW_retry = 0, tmp;
 	u32 fwdl_start_time;
 	struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
@@ -591,6 +640,7 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 	u8 *pFirmwareBuf;
 	u32 FirmwareLen;
 	static int log_version;
+	int error;
 
 	if (!dvobj->firmware.szFwBuffer)
 		rtStatus = load_firmware(&dvobj->firmware, device);
@@ -621,7 +671,10 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 
 	/*  Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */
 	/*  or it will cause download Fw fail. 2010.02.01. by tynli. */
-	if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */
+	error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+	if (error) {
+		return _FAIL;
+	} else if (tmp & RAM_DL_SEL) { /* 8051 RAM code */
 		rtw_write8(padapter, REG_MCUFWDL, 0x00);
 		_8051Reset88E(padapter);
 	}
@@ -630,7 +683,11 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
 	fwdl_start_time = jiffies;
 	while (1) {
 		/* reset the FWDL chksum */
-		rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
+		error = rtw_read8(padapter, REG_MCUFWDL, &tmp);
+		if (error)
+			return _FAIL;
+
+		rtw_write8(padapter, REG_MCUFWDL, tmp | FWDL_ChkSum_rpt);
 
 		rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
 
@@ -715,6 +772,7 @@ hal_EfusePowerSwitch_RTL8188E(
 {
 	u8 tempval;
 	u16	tmpV16;
+	int error;
 
 	if (PwrState) {
 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
@@ -741,7 +799,10 @@ hal_EfusePowerSwitch_RTL8188E(
 
 		if (bWrite) {
 			/*  Enable LDO 2.5V before read/write action */
-			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+			error = rtw_read8(pAdapter, EFUSE_TEST + 3, &tempval);
+			if (error)
+				return;
+
 			tempval &= 0x0F;
 			tempval |= (VOLTAGE_V25 << 4);
 			rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
@@ -751,7 +812,9 @@ hal_EfusePowerSwitch_RTL8188E(
 
 		if (bWrite) {
 			/*  Disable LDO 2.5V after read/write action */
-			tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
+			error = rtw_read8(pAdapter, EFUSE_TEST + 3, &tempval);
+			if (error)
+				return;
 			rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
 		}
 	}
@@ -1784,12 +1847,19 @@ void rtl8188e_stop_thread(struct adapter *padapter)
 
 static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
 {
+	int error;
+	u8 tmp;
+
+	error = rtw_read8(adapter, rOFDM0_RxDSP + 1, &tmp);
+	if (error)
+		return;
+
 	if (enable) {
 		DBG_88E("Enable notch filter\n");
-		rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
+		rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp | BIT(1));
 	} else {
 		DBG_88E("Disable notch filter\n");
-		rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
+		rtw_write8(adapter, rOFDM0_RxDSP + 1, tmp & ~BIT(1));
 	}
 }
 void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 30a9dca8f453..f6d4c91a97a2 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -960,6 +960,7 @@ _PHY_SetBWMode92C(
 	struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
 	u8 regBwOpMode;
 	u8 regRRSR_RSC;
+	int error;
 
 	if (pHalData->rf_chip == RF_PSEUDO_11N)
 		return;
@@ -975,8 +976,13 @@ _PHY_SetBWMode92C(
 	/* 3<1>Set MAC register */
 	/* 3 */
 
-	regBwOpMode = rtw_read8(Adapter, REG_BWOPMODE);
-	regRRSR_RSC = rtw_read8(Adapter, REG_RRSR + 2);
+	error = rtw_read8(Adapter, REG_BWOPMODE, &regBwOpMode);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_RRSR + 2, &regRRSR_RSC);
+	if (error)
+		return;
 
 	switch (pHalData->CurrentChannelBW) {
 	case HT_CHANNEL_WIDTH_20:
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 16fa249e35d3..39dacfb23570 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -49,13 +49,17 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
 {
 	u32 rx_dma_status = 0;
 	u8 fw_status = 0;
+	int error;
+
 	rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
 	if (rx_dma_status != 0x00) {
 		DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
 		rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
 	}
-	fw_status = rtw_read8(padapter, REG_FMETHR);
-	if (fw_status != 0x00) {
+	error = rtw_read8(padapter, REG_FMETHR, &fw_status);
+	if (error) {
+		return;
+	} else if (fw_status != 0x00) {
 		if (fw_status == 1)
 			DBG_88E("%s REG_FW_STATUS (0x%02x), Read_Efuse_Fail !!\n", __func__, fw_status);
 		else if (fw_status == 2)
diff --git a/drivers/staging/r8188eu/hal/rtl8188eu_led.c b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
index 452d4bb87aba..7f793b7ce609 100644
--- a/drivers/staging/r8188eu/hal/rtl8188eu_led.c
+++ b/drivers/staging/r8188eu/hal/rtl8188eu_led.c
@@ -14,10 +14,15 @@
 void SwLedOn(struct adapter *padapter, struct LED_871x *pLed)
 {
 	u8	LedCfg;
+	int error;
 
 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
 		return;
-	LedCfg = rtw_read8(padapter, REG_LEDCFG2);
+
+	error = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);
+	if (error)
+		return;
+
 	switch (pLed->LedPin) {
 	case LED_PIN_LED0:
 		rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /*  SW control led0 on. */
@@ -37,11 +42,14 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
 {
 	u8	LedCfg;
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
+	int error;
 
 	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
 		goto exit;
 
-	LedCfg = rtw_read8(padapter, REG_LEDCFG2);/* 0x4E */
+	error = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);/* 0x4E */
+	if (error)
+		return;
 
 	switch (pLed->LedPin) {
 	case LED_PIN_LED0:
@@ -49,7 +57,11 @@ void SwLedOff(struct adapter *padapter, struct LED_871x *pLed)
 			/*  Open-drain arrangement for controlling the LED) */
 			LedCfg &= 0x90; /*  Set to software control. */
 			rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
-			LedCfg = rtw_read8(padapter, REG_MAC_PINMUX_CFG);
+
+			error = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &LedCfg);
+			if (error)
+				return;
+
 			LedCfg &= 0xFE;
 			rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
 		} else {
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 5cdabf43d4fd..4f1d7f9b43c3 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -120,6 +120,7 @@ static void _InitInterrupt(struct adapter *Adapter)
 	u32 imr, imr_ex;
 	u8  usb_opt;
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
+	int error;
 
 	/* HISR write one to clear */
 	rtw_write32(Adapter, REG_HISR_88E, 0xFFFFFFFF);
@@ -135,7 +136,9 @@ static void _InitInterrupt(struct adapter *Adapter)
 	/*  REG_USB_SPECIAL_OPTION - BIT(4) */
 	/*  0; Use interrupt endpoint to upload interrupt pkt */
 	/*  1; Use bulk endpoint to upload interrupt pkt, */
-	usb_opt = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+	error = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &usb_opt);
+	if (error)
+		return;
 
 	if (!adapter_to_dvobj(Adapter)->ishighspeed)
 		usb_opt = usb_opt & (~INT_BULK_SEL);
@@ -435,8 +438,12 @@ static void _InitRxSetting(struct adapter *Adapter)
 static void _InitRetryFunction(struct adapter *Adapter)
 {
 	u8 value8;
+	int error;
+
+	error = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL, &value8);
+	if (error)
+		return;
 
-	value8 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL);
 	value8 |= EN_AMPDU_RTY_NEW;
 	rtw_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
 
@@ -499,9 +506,15 @@ usb_AggSettingRxUpdate(
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	u8 valueDMA;
 	u8 valueUSB;
+	int error;
 
-	valueDMA = rtw_read8(Adapter, REG_TRXDMA_CTRL);
-	valueUSB = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION);
+	error = rtw_read8(Adapter, REG_TRXDMA_CTRL, &valueDMA);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_USB_SPECIAL_OPTION, &valueUSB);
+	if (error)
+		return;
 
 	switch (haldata->UsbRxAggMode) {
 	case USB_RX_AGG_DMA:
@@ -589,6 +602,7 @@ static void _InitOperationMode(struct adapter *Adapter)
 static void _InitBeaconParameters(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
+	int error;
 
 	rtw_write16(Adapter, REG_BCN_CTRL, 0x1010);
 
@@ -601,11 +615,25 @@ static void _InitBeaconParameters(struct adapter *Adapter)
 	/*  beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
 	rtw_write16(Adapter, REG_BCNTCFG, 0x660F);
 
-	haldata->RegBcnCtrlVal = rtw_read8(Adapter, REG_BCN_CTRL);
-	haldata->RegTxPause = rtw_read8(Adapter, REG_TXPAUSE);
-	haldata->RegFwHwTxQCtrl = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2);
-	haldata->RegReg542 = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2);
-	haldata->RegCR_1 = rtw_read8(Adapter, REG_CR + 1);
+	error = rtw_read8(Adapter, REG_BCN_CTRL, (u8 *) &haldata->RegBcnCtrlVal);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_TXPAUSE, &haldata->RegTxPause);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL + 2, &haldata->RegFwHwTxQCtrl);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2, &haldata->RegReg542);
+	if (error)
+		return;
+
+	error = rtw_read8(Adapter, REG_CR + 1, &haldata->RegCR_1);
+	if (error)
+		return;
 }
 
 static void _BeaconFunctionEnable(struct adapter *Adapter,
@@ -665,14 +693,27 @@ enum rt_rf_power_state RfOnOffDetect(struct adapter *adapt)
 {
 	u8 val8;
 	enum rt_rf_power_state rfpowerstate = rf_off;
+	int error;
 
 	if (adapt->pwrctrlpriv.bHWPowerdown) {
-		val8 = rtw_read8(adapt, REG_HSISR);
+		error = rtw_read8(adapt, REG_HSISR, &val8);
+		if (error)
+			return rfpowerstate;
+
 		DBG_88E("pwrdown, 0x5c(BIT(7))=%02x\n", val8);
 		rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on;
 	} else { /*  rf on/off */
-		rtw_write8(adapt, REG_MAC_PINMUX_CFG, rtw_read8(adapt, REG_MAC_PINMUX_CFG) & ~(BIT(3)));
-		val8 = rtw_read8(adapt, REG_GPIO_IO_SEL);
+
+		error = rtw_read8(adapt, REG_MAC_PINMUX_CFG, &val8);
+		if (error)
+			return rfpowerstate;
+
+		rtw_write8(adapt, REG_MAC_PINMUX_CFG, val8 & ~(BIT(3)));
+
+		error = rtw_read8(adapt, REG_GPIO_IO_SEL, &val8);
+		if (error)
+			return rfpowerstate;
+
 		DBG_88E("GPIO_IN=%02x\n", val8);
 		rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
 	}
@@ -689,6 +730,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	struct pwrctrl_priv		*pwrctrlpriv = &Adapter->pwrctrlpriv;
 	struct registry_priv	*pregistrypriv = &Adapter->registrypriv;
 	u32 init_start_time = jiffies;
+	int error;
 
 	#define HAL_INIT_PROFILE_TAG(stage) do {} while (0)
 
@@ -835,7 +877,11 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 
 	/* Enable TX Report */
 	/* Enable Tx Report Timer */
-	value8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+	error = rtw_read8(Adapter, REG_TX_RPT_CTRL, &value8);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
 	rtw_write8(Adapter,  REG_TX_RPT_CTRL, (value8 | BIT(1) | BIT(0)));
 	/* Set MAX RPT MACID */
 	rtw_write8(Adapter,  REG_TX_RPT_CTRL + 1, 2);/* FOR sta mode ,0: bc/mc ,1:AP */
@@ -962,9 +1008,13 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 {
 	u8 val8;
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(Adapter);
+	int error;
 
 	/* Stop Tx Report Timer. 0x4EC[Bit1]=b'0 */
-	val8 = rtw_read8(Adapter, REG_TX_RPT_CTRL);
+	error = rtw_read8(Adapter, REG_TX_RPT_CTRL, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_TX_RPT_CTRL, val8 & (~BIT(1)));
 
 	/*  stop rx */
@@ -975,10 +1025,15 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 
 	/*  2. 0x1F[7:0] = 0		turn off RF */
 
-	val8 = rtw_read8(Adapter, REG_MCUFWDL);
-	if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
+	error = rtw_read8(Adapter, REG_MCUFWDL, &val8);
+	if (error) {
+		return;
+	} else if ((val8 & RAM_DL_SEL) && Adapter->bFWReady) { /* 8051 RAM code */
 		/*  Reset MCU 0x2[10]=0. */
-		val8 = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1);
+		error = rtw_read8(Adapter, REG_SYS_FUNC_EN + 1, &val8);
+		if (error)
+			return;
+
 		val8 &= ~BIT(2);	/*  0x2[10], FEN_CPUEN */
 		rtw_write8(Adapter, REG_SYS_FUNC_EN + 1, val8);
 	}
@@ -988,26 +1043,43 @@ static void CardDisableRTL8188EU(struct adapter *Adapter)
 
 	/* YJ,add,111212 */
 	/* Disable 32k */
-	val8 = rtw_read8(Adapter, REG_32K_CTRL);
+	error = rtw_read8(Adapter, REG_32K_CTRL, &val8);
+	if (error)
+		return;
 	rtw_write8(Adapter, REG_32K_CTRL, val8 & (~BIT(0)));
 
 	/*  Card disable power action flow */
 	HalPwrSeqCmdParsing(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, Rtl8188E_NIC_DISABLE_FLOW);
 
 	/*  Reset MCU IO Wrapper */
-	val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+	error = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_RSV_CTRL + 1, (val8 & (~BIT(3))));
-	val8 = rtw_read8(Adapter, REG_RSV_CTRL + 1);
+	error = rtw_read8(Adapter, REG_RSV_CTRL + 1, &val8);
+	if (error)
+		return;
 	rtw_write8(Adapter, REG_RSV_CTRL + 1, val8 | BIT(3));
 
 	/* YJ,test add, 111207. For Power Consumption. */
-	val8 = rtw_read8(Adapter, GPIO_IN);
+	error = rtw_read8(Adapter, GPIO_IN, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, GPIO_OUT, val8);
 	rtw_write8(Adapter, GPIO_IO_SEL, 0xFF);/* Reg0x46 */
 
-	val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL);
+	error = rtw_read8(Adapter, REG_GPIO_IO_SEL, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_GPIO_IO_SEL, (val8 << 4));
-	val8 = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1);
+
+	error = rtw_read8(Adapter, REG_GPIO_IO_SEL + 1, &val8);
+	if (error)
+		return;
+
 	rtw_write8(Adapter, REG_GPIO_IO_SEL + 1, val8 | 0x0F);/* Reg0x43 */
 	rtw_write32(Adapter, REG_BB_PAD_CTRL, 0x00080808);/* set LNA ,TRSW,EX_PA Pin to output mode */
 	haldata->bMacPwrCtrlOn = false;
@@ -1181,9 +1253,13 @@ static void _ReadPROMContent(
 {
 	struct eeprom_priv *eeprom = GET_EEPROM_EFUSE_PRIV(Adapter);
 	u8 eeValue;
+	int error;
 
 	/* check system boot selection */
-	eeValue = rtw_read8(Adapter, REG_9346CR);
+	error = rtw_read8(Adapter, REG_9346CR, &eeValue);
+	if (error)
+		return;
+
 	eeprom->EepromOrEfuse		= (eeValue & BOOT_FROM_EEPROM) ? true : false;
 	eeprom->bautoload_fail_flag	= (eeValue & EEPROM_EN) ? false : true;
 
@@ -1262,12 +1338,21 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
 {
 	u8 val8;
 	u8 mode = *((u8 *)val);
+	int error;
+
+	error = rtw_read8(Adapter, REG_BCN_CTRL, &val8);
+	if (error)
+		return;
 
 	/*  disable Port0 TSF update */
-	rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+	rtw_write8(Adapter, REG_BCN_CTRL, val8 | BIT(4));
 
 	/*  set net_type */
-	val8 = rtw_read8(Adapter, MSR) & 0x0c;
+	error = rtw_read8(Adapter, MSR, &val8);
+	if (error)
+		return;
+
+	val8 &= 0x0c;
 	val8 |= mode;
 	rtw_write8(Adapter, MSR, val8);
 
@@ -1304,14 +1389,20 @@ static void hw_var_set_opmode(struct adapter *Adapter, u8 variable, u8 *val)
 		rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));
 
 		/* BIT(3) - If set 0, hw will clr bcnq when tx becon ok/fail or port 0 */
-		rtw_write8(Adapter, REG_MBID_NUM, rtw_read8(Adapter, REG_MBID_NUM) | BIT(3) | BIT(4));
+		error = rtw_read8(Adapter, REG_MBID_NUM, &val8);
+		if (error)
+			return;
+		rtw_write8(Adapter, REG_MBID_NUM, val8 | BIT(3) | BIT(4));
 
 		/* enable BCN0 Function for if1 */
 		/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
 		rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT0_NORMAL_CHIP | EN_BCN_FUNCTION | BIT(1)));
 
 		/* dis BCN1 ATIM  WND if if2 is station */
-		rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | BIT(0));
+		error = rtw_read8(Adapter, REG_BCN_CTRL_1, &val8);
+		if (error)
+			return;
+		rtw_write8(Adapter, REG_BCN_CTRL_1, val8 | BIT(0));
 	}
 }
 
@@ -1345,8 +1436,16 @@ static void hw_var_set_bcn_func(struct adapter *Adapter, u8 variable, u8 *val)
 
 	if (*((u8 *)val))
 		rtw_write8(Adapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
-	else
-		rtw_write8(Adapter, bcn_ctrl_reg, rtw_read8(Adapter, bcn_ctrl_reg) & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+	else {
+		u8 tmp;
+		int error;
+
+		error = rtw_read8(Adapter, bcn_ctrl_reg, &tmp);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, bcn_ctrl_reg, tmp & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT)));
+	}
 }
 
 static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
@@ -1354,13 +1453,19 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	struct dm_priv	*pdmpriv = &haldata->dmpriv;
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+	int error;
+	u8 tmp;
 
 	switch (variable) {
 	case HW_VAR_MEDIA_STATUS:
 		{
 			u8 val8;
 
-			val8 = rtw_read8(Adapter, MSR) & 0x0c;
+			error = rtw_read8(Adapter, MSR, &val8);
+			if (error)
+				return;
+
+			val8 &= 0x0c;
 			val8 |= *((u8 *)val);
 			rtw_write8(Adapter, MSR, val8);
 		}
@@ -1369,7 +1474,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			u8 val8;
 
-			val8 = rtw_read8(Adapter, MSR) & 0x03;
+			error = rtw_read8(Adapter, MSR, &val8);
+			if (error)
+				return;
+
+			val8 &= 0x03;
 			val8 |= *((u8 *)val) << 2;
 			rtw_write8(Adapter, MSR, val8);
 		}
@@ -1407,7 +1516,12 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			/*  Set RRSR rate table. */
 			rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
 			rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
-			rtw_write8(Adapter, REG_RRSR + 2, rtw_read8(Adapter, REG_RRSR + 2) & 0xf0);
+
+			error = rtw_read8(Adapter, REG_RRSR + 2, &tmp);
+			if (error)
+				return;
+
+			rtw_write8(Adapter, REG_RRSR + 2, tmp & 0xf0);
 
 			/*  Set RTS initial rate */
 			while (BrateCfg > 0x1) {
@@ -1437,13 +1551,21 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				StopTxBeacon(Adapter);
 
 			/* disable related TSF function */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(3)));
+			error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+			if (error)
+				return;
+
+			rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(3)));
 
 			rtw_write32(Adapter, REG_TSFTR, tsf);
 			rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
 
 			/* enable related TSF function */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(3));
+			error =  rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+			if (error)
+				return;
+
+			rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(3));
 
 			if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
 				ResumeTxBeacon(Adapter);
@@ -1471,35 +1593,48 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
 
 		/* disable update TSF */
-		rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+		error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
 		break;
 	case HW_VAR_MLME_SITESURVEY:
 		if (*((u8 *)val)) { /* under sitesurvey */
 			/* config RCR to receive different BSSID & not to receive data frame */
 			u32 v = rtw_read32(Adapter, REG_RCR);
+
 			v &= ~(RCR_CBSSID_BCN);
 			rtw_write32(Adapter, REG_RCR, v);
 			/* reject all data frame */
 			rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
 
 			/* disable update TSF */
-			rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | BIT(4));
+			error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+			if (error)
+				return;
+			rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
 		} else { /* sitesurvey done */
 			struct mlme_ext_priv	*pmlmeext = &Adapter->mlmeextpriv;
 			struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
 
+			error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+			if (error)
+				return;
+
 			if ((is_client_associated_to_ap(Adapter)) ||
 			    ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
 				/* enable to rx data frame */
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
 			} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
 			}
+
 			if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
 				rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
 			} else {
@@ -1517,6 +1652,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			u8 RetryLimit = 0x30;
 			u8 type = *((u8 *)val);
+			u8 tmp;
 			struct mlme_priv	*pmlmepriv = &Adapter->mlmepriv;
 
 			if (type == 0) { /*  prepare to join */
@@ -1541,7 +1677,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			} else if (type == 2) {
 				/* sta add event call back */
 				/* enable update TSF */
-				rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) & (~BIT(4)));
+				error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
+				if (error)
+					return;
+
+				rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
 
 				if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
 					RetryLimit = 0x7;
@@ -1671,7 +1811,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	case HW_VAR_ACM_CTRL:
 		{
 			u8 acm_ctrl = *((u8 *)val);
-			u8 AcmCtrl = rtw_read8(Adapter, REG_ACMHWCTRL);
+			u8 AcmCtrl;
+
+			error = rtw_read8(Adapter, REG_ACMHWCTRL, &AcmCtrl);
+			if (error)
+				return;
 
 			if (acm_ctrl > 1)
 				AcmCtrl = AcmCtrl | 0x1;
@@ -1699,6 +1843,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			u8 MinSpacingToSet;
 			u8 SecMinSpace;
+			u8 tmp;
 
 			MinSpacingToSet = *((u8 *)val);
 			if (MinSpacingToSet <= 7) {
@@ -1719,7 +1864,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				}
 				if (MinSpacingToSet < SecMinSpace)
 					MinSpacingToSet = SecMinSpace;
-				rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (rtw_read8(Adapter, REG_AMPDU_MIN_SPACE) & 0xf8) | MinSpacingToSet);
+
+				error = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &tmp);
+				if (error)
+					return;
+
+				rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (tmp & 0xf8) |
+					  MinSpacingToSet);
 			}
 		}
 		break;
@@ -1868,7 +2019,13 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		break;
 	case HW_VAR_BCN_VALID:
 		/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
-		rtw_write8(Adapter, REG_TDECTRL + 2, rtw_read8(Adapter, REG_TDECTRL + 2) | BIT(0));
+		u8 tmp;
+
+		error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
+		if (error)
+			return;
+
+		rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
 		break;
 	default:
 		break;
@@ -1880,17 +2037,23 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
+	int error;
+	u8 tmp;
 
 	switch (variable) {
 	case HW_VAR_BASIC_RATE:
 		*((u16 *)(val)) = haldata->BasicRateSet;
 		fallthrough;
 	case HW_VAR_TXPAUSE:
-		val[0] = rtw_read8(Adapter, REG_TXPAUSE);
+		error = rtw_read8(Adapter, REG_TXPAUSE, val);
 		break;
 	case HW_VAR_BCN_VALID:
 		/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */
-		val[0] = (BIT(0) & rtw_read8(Adapter, REG_TDECTRL + 2)) ? true : false;
+		error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
+		if (error)
+			break;
+
+		val[0] = (BIT(0) & tmp) ? true : false;
 		break;
 	case HW_VAR_DM_FLAG:
 		val[0] = podmpriv->SupportAbility;
@@ -2035,6 +2198,7 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	u8 bResult = _SUCCESS;
+	int error;
 
 	switch (eVariable) {
 	case HAL_DEF_DBG_DM_FUNC:
@@ -2058,7 +2222,10 @@ static u8 SetHalDefVar8188EUsb(struct adapter *Adapter, enum hal_def_variable eV
 			} else if (dm_func == 6) {/* turn on all dynamic func */
 				if (!(podmpriv->SupportAbility  & DYNAMIC_BB_DIG)) {
 					struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
-					pDigTable->CurIGValue = rtw_read8(Adapter, 0xc50);
+
+					error = rtw_read8(Adapter, 0xc50, &pDigTable->CurIGValue);
+					if (error)
+						return _FAIL;
 				}
 				podmpriv->SupportAbility = DYNAMIC_ALL_FUNC_ENABLE;
 				DBG_88E("==> Turn on all dynamic function...\n");
@@ -2168,6 +2335,8 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 	struct mlme_ext_priv	*pmlmeext = &adapt->mlmeextpriv;
 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
 	u32 bcn_ctrl_reg			= REG_BCN_CTRL;
+	int error;
+	u8 tmp;
 	/* reset TSF, enable update TSF, correcting TSF On Beacon */
 
 	/* BCN interval */
@@ -2193,7 +2362,11 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 
 	ResumeTxBeacon(adapt);
 
-	rtw_write8(adapt, bcn_ctrl_reg, rtw_read8(adapt, bcn_ctrl_reg) | BIT(1));
+	error = rtw_read8(adapt, bcn_ctrl_reg, &tmp);
+	if (error)
+		return;
+
+	rtw_write8(adapt, bcn_ctrl_reg, tmp | BIT(1));
 }
 
 static void rtl8188eu_init_default_value(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index 953fa05dc30c..c4f114c3d571 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -101,26 +101,28 @@ static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u16 value, void *pdata,
 	return status;
 }
 
-static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read8(struct intf_hdl *pintfhdl, u32 addr, u8 *data)
 {
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
-	u8 data = 0;
-
+	int res;
 
+	if (WARN_ON(unlikely(!data)))
+		return -EINVAL;
 
 	requesttype = 0x01;/* read_in */
 
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 1;
 
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
-
-
-
-	return data;
+	res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
+	if (res < 0) {
+		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 8 bytes: %d\n", res);
+		return res;
+	}
 
+	return 0;
 }
 
 static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 6b589413d56c..8e531d272927 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -60,7 +60,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext);
 
 /*  =========== EXtern Function Prototype */
 
-u8 ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
 
 u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
 
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index f1b3074fa075..fd99b36abca6 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -85,7 +85,7 @@ struct intf_hdl;
 struct io_queue;
 
 struct _io_ops {
-	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
+	int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
 	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
 	u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
 	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
@@ -248,7 +248,7 @@ void unregister_intf_hdl(struct intf_hdl *pintfhdl);
 void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 
-u8 _rtw_read8(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
 u16 _rtw_read16(struct adapter *adapter, u32 addr);
 u32 _rtw_read32(struct adapter *adapter, u32 addr);
 void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
@@ -270,7 +270,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
 			     u8 *pmem, int timeout_ms);
 void _rtw_write_port_cancel(struct adapter *adapter);
 
-#define rtw_read8(adapter, addr) _rtw_read8((adapter), (addr))
+#define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
 #define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
 #define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
 #define rtw_read_mem(adapter, addr, cnt, mem)				\
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index ab4a9200f079..c9f0772bcbe1 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2074,6 +2074,7 @@ static int rtw_wx_read32(struct net_device *dev,
 	u32 data32;
 	u32 bytes;
 	u8 *ptmp;
+	int error;
 
 	padapter = (struct adapter *)rtw_netdev_priv(dev);
 	p = &wrqu->data;
@@ -2093,7 +2094,10 @@ static int rtw_wx_read32(struct net_device *dev,
 
 	switch (bytes) {
 	case 1:
-		data32 = rtw_read8(padapter, addr);
+		error = rtw_read8(padapter, addr, (u8 *) &data32);
+		if (error)
+			return error;
+
 		sprintf(extra, "0x%02X", data32);
 		break;
 	case 2:
@@ -2251,6 +2255,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 	u8 path;
 	u8 offset;
 	u32 value;
+	int error;
 
 	DBG_88E("%s\n", __func__);
 
@@ -2262,7 +2267,8 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 		RegRWStruct = (struct mp_rw_reg *)pdata;
 		switch (RegRWStruct->width) {
 		case 1:
-			RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
+			error = rtw_read8(padapter, RegRWStruct->offset,
+					 (u8 *) &RegRWStruct->value);
 			break;
 		case 2:
 			RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
@@ -3964,6 +3970,8 @@ static int rtw_dbg_port(struct net_device *dev,
 	struct security_priv *psecuritypriv = &padapter->securitypriv;
 	struct wlan_network *cur_network = &pmlmepriv->cur_network;
 	struct sta_priv *pstapriv = &padapter->stapriv;
+	int error;
+	u32 tmp;
 
 	pdata = (u32 *)&wrqu->data;
 
@@ -3978,7 +3986,8 @@ static int rtw_dbg_port(struct net_device *dev,
 	case 0x70:/* read_reg */
 		switch (minor_cmd) {
 		case 1:
-			DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+			if (!rtw_read8(padapter, arg, (u8 *) &tmp))
+				DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
 			break;
 		case 2:
 			DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
@@ -3992,7 +4001,9 @@ static int rtw_dbg_port(struct net_device *dev,
 		switch (minor_cmd) {
 		case 1:
 			rtw_write8(padapter, arg, extra_arg);
-			DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, rtw_read8(padapter, arg));
+			if (rtw_read8(padapter, arg, (u8 *) &tmp))
+				DBG_88E("rtw_write8(0x%x) = 0x%02x\n", arg, (u8) tmp);
+
 			break;
 		case 2:
 			rtw_write16(padapter, arg, extra_arg);
@@ -4096,8 +4107,10 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read8(padapter, reg);
-			if (start_value + write_num - 1 == final)
+			error = rtw_read8(padapter, reg, &final);
+			if (error)
+				return error;
+			else if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
 			else
 				DBG_88E("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
@@ -4423,13 +4436,16 @@ static int rtw_dbg_port(struct net_device *dev,
 
 		case 0xfd:
 			rtw_write8(padapter, 0xc50, arg);
-			DBG_88E("wr(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
+			DBG_88E_REG8("wr(0xc50) = 0x%x\n", padapter, 0xc50);
 			rtw_write8(padapter, 0xc58, arg);
-			DBG_88E("wr(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+			error = rtw_read8(padapter, 0xc58, (u8 *) &tmp);
+			if (error)
+				return error;
+			DBG_88E("wr(0xc58) = 0x%x\n", (u8) tmp);
 			break;
 		case 0xfe:
-			DBG_88E("rd(0xc50) = 0x%x\n", rtw_read8(padapter, 0xc50));
-			DBG_88E("rd(0xc58) = 0x%x\n", rtw_read8(padapter, 0xc58));
+			DBG_88E_REG8("rd(0xc50) = 0x%x\n", padapter, 0xc50);
+			DBG_88E_REG8("rd(0xc58) = 0x%x\n", padapter, 0xc58);
 			break;
 		case 0xff:
 			DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
@@ -5326,6 +5342,8 @@ static int rtw_mp_read_reg(struct net_device *dev,
 	char data[20], tmp[20];
 	u32 addr;
 	u32 ret, i = 0, j = 0, strtout = 0;
+	u32 val32;
+	int error;
 
 	if (!input)
 		return -ENOMEM;
@@ -5361,7 +5379,10 @@ static int rtw_mp_read_reg(struct net_device *dev,
 	switch (width) {
 	case 'b':
 		/*  1 byte */
-		sprintf(extra, "%d\n",  rtw_read8(padapter, addr));
+		error = rtw_read8(padapter, addr, (u8 *) &val32);
+		if (error)
+			return error;
+		sprintf(extra, "%d\n", (u8) val32);
 		wrqu->length = strlen(extra);
 		break;
 	case 'w':
@@ -5889,6 +5910,8 @@ static int rtw_mp_arx(struct net_device *dev,
 	u32 cckok = 0, cckcrc = 0, ofdmok = 0, ofdmcrc = 0, htok = 0, htcrc = 0, OFDM_FA = 0, CCK_FA = 0;
 	char	*input = kmalloc(wrqu->length, GFP_KERNEL);
 	struct adapter *padapter = rtw_netdev_priv(dev);
+	int error = 0;
+	u8 tmp;
 
 	if (!input)
 		return -ENOMEM;
@@ -5934,13 +5957,25 @@ static int rtw_mp_arx(struct net_device *dev,
 		OFDM_FA = read_bbreg(padapter, 0xda4, 0x0000FFFF);
 		OFDM_FA = read_bbreg(padapter, 0xda4, 0xFFFF0000);
 		OFDM_FA = read_bbreg(padapter, 0xda8, 0x0000FFFF);
-		CCK_FA = (rtw_read8(padapter, 0xa5b) << 8) | (rtw_read8(padapter, 0xa5c));
+
+		error = rtw_read8(padapter, 0xa5b, &tmp);
+		if (error)
+			goto end;
+
+		CCK_FA = tmp << 8;
+
+		error = rtw_read8(padapter, 0xa5c, &tmp);
+		if (error)
+			goto end;
+
+		CCK_FA |= tmp;
 
 		sprintf(extra, "Phy Received packet OK:%d CRC error:%d FA Counter: %d", cckok + ofdmok + htok, cckcrc + ofdmcrc + htcrc, OFDM_FA + CCK_FA);
 	}
 	wrqu->length = strlen(extra) + 1;
+end:
 	kfree(input);
-	return 0;
+	return error;
 }
 
 static int rtw_mp_trx_query(struct net_device *dev,
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
                                         ` (2 preceding siblings ...)
  2021-08-24  7:27                       ` [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8 Pavel Skripkin
@ 2021-08-24  7:27                       ` Pavel Skripkin
  2021-08-25  4:35                         ` Fabio M. De Francesco
  2021-08-26 10:50                         ` Greg KH
  2021-08-24  7:27                       ` [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32 Pavel Skripkin
                                         ` (3 subsequent siblings)
  7 siblings, 2 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  7:27 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

_rtw_read16 function can fail in case of usb transfer failure. But
previous function prototype wasn't designed to return an error to
caller. It can cause a lot uninit value bugs all across the driver code,
since rtw_read16() returns local stack variable to caller.

Fix it by changing the prototype of this function. Now it returns an
int: 0 on success, negative error value on failure and callers should pass
the pointer to storage location for register value.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_debug.c      |  7 +++-
 drivers/staging/r8188eu/core/rtw_io.c         |  9 ++---
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  4 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |  4 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 29 +++++++++++----
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  5 ++-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 37 ++++++++++++++++---
 drivers/staging/r8188eu/hal/usb_ops_linux.c   | 22 +++++++++--
 .../staging/r8188eu/include/odm_interface.h   |  2 +-
 drivers/staging/r8188eu/include/rtw_io.h      |  6 +--
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 28 +++++++++++---
 11 files changed, 115 insertions(+), 38 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index 8b7d3eb12bd0..a41675e101ac 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -91,7 +91,12 @@ int proc_get_read_reg(char *page, char **start,
 				proc_get_read_addr, (u8) tmp);
 		break;
 	case 2:
-		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
+		error = rtw_read16(padapter, proc_get_read_addr, (u16 *) &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n",
+				proc_get_read_addr, (u16) tmp);
 		break;
 	case 4:
 		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index 2714506c8ffb..fd64893c778d 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -45,18 +45,15 @@ int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
 	return _read8(pintfhdl, addr, data);
 }
 
-u16 _rtw_read16(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
 {
-	u16 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
-	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+	int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
 
 	_read16 = pintfhdl->io_ops._read16;
 
-	r_val = _read16(pintfhdl, addr);
-
-	return r_val;
+	return _read16(pintfhdl, addr, data);
 }
 
 u32 _rtw_read32(struct adapter *adapter, u32 addr)
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index 894ab456f202..c6f7636c2174 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -653,7 +653,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 			status = NDIS_STATUS_NOT_ACCEPTED;
 		break;
 	case 2:
-		RegRWStruct->value = rtw_read16(Adapter, offset);
+		error = rtw_read16(Adapter, offset, (u16 *) &RegRWStruct->value);
+		if (error)
+			status = NDIS_STATUS_NOT_ACCEPTED;
 		break;
 	default:
 		width = 4;
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 9a9df98da727..669d3e5eafb6 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -10,10 +10,10 @@ int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data)
 	return rtw_read8(Adapter, RegAddr, data);
 }
 
-u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read16(Adapter, RegAddr);
+	return rtw_read16(Adapter, RegAddr, data);
 }
 
 u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index cfc429965b7d..94e2828c328e 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -262,7 +262,11 @@ static void efuse_read_phymap_from_txpktbuf(
 			 * do not remove it as the rtw_read16() call consumes
 			 * 2 bytes from the EEPROM source.
 			 */
-			u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
+			u16 lenc;
+
+			error = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, &lenc);
+			if (error)
+				return;
 
 			len = le32_to_cpu(lo32) & 0x0000ffff;
 
@@ -778,21 +782,27 @@ hal_EfusePowerSwitch_RTL8188E(
 		rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
 
 		/*  1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
-		tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
-		if (!(tmpV16 & PWC_EV12V)) {
+		error = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
+		if (error) {
+			return;
+		} else if (!(tmpV16 & PWC_EV12V)) {
 			tmpV16 |= PWC_EV12V;
 			rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
 		}
 		/*  Reset: 0x0000h[28], default valid */
-		tmpV16 =  rtw_read16(pAdapter, REG_SYS_FUNC_EN);
-		if (!(tmpV16 & FEN_ELDR)) {
+		error = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
+		if (error) {
+			return;
+		} else if (!(tmpV16 & FEN_ELDR)) {
 			tmpV16 |= FEN_ELDR;
 			rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
 		}
 
 		/*  Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
-		tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
-		if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
+		error = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
+		if (error) {
+			return;
+		} else if ((!(tmpV16 & LOADER_CLK_EN))  || (!(tmpV16 & ANA8M))) {
 			tmpV16 |= (LOADER_CLK_EN | ANA8M);
 			rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
 		}
@@ -1915,8 +1925,11 @@ u8 GetEEPROMSize8188E(struct adapter *padapter)
 {
 	u8 size = 0;
 	u32	cr;
+	int error;
 
-	cr = rtw_read16(padapter, REG_9346CR);
+	error = rtw_read16(padapter, REG_9346CR, (u16 *) &cr);
+	if (error)
+		return size;
 	/*  6: EEPROM used is 93C46, 4: boot from E-Fuse. */
 	size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
 
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index f6d4c91a97a2..3afb66195413 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -577,11 +577,14 @@ PHY_BBConfig8188E(
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(Adapter);
 	u32 RegVal;
 	u8 CrystalCap;
+	int error;
 
 	phy_InitBBRFRegisterDefinition(Adapter);
 
 	/*  Enable BB and RF */
-	RegVal = rtw_read16(Adapter, REG_SYS_FUNC_EN);
+	error = rtw_read16(Adapter, REG_SYS_FUNC_EN, (u16 *) &RegVal);
+	if (error)
+		return _FAIL;
 	rtw_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal | BIT(13) | BIT(0) | BIT(1)));
 
 	/*  20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 4f1d7f9b43c3..4ecccc6499aa 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -90,6 +90,8 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
 	u16 value16;
 	/*  HW Power on sequence */
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(adapt);
+	int error;
+
 	if (haldata->bMacPwrCtrlOn)
 		return _SUCCESS;
 
@@ -103,7 +105,10 @@ static u32 rtl8188eu_InitPowerOn(struct adapter *adapt)
 	rtw_write16(adapt, REG_CR, 0x00);  /* suggseted by zhouzhou, by page, 20111230 */
 
 		/*  Enable MAC DMA/WMAC/SCHEDULE/SEC block */
-	value16 = rtw_read16(adapt, REG_CR);
+	error = rtw_read16(adapt, REG_CR, &value16);
+	if (error)
+		return _FAIL;
+
 	value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
 				| PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
 	/*  for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31. */
@@ -207,7 +212,14 @@ static void _InitNormalChipRegPriority(struct adapter *Adapter, u16 beQ,
 				       u16 bkQ, u16 viQ, u16 voQ, u16 mgtQ,
 				       u16 hiQ)
 {
-	u16 value16	= (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
+	u16 value16;
+	int error;
+
+	error = rtw_read16(Adapter, REG_TRXDMA_CTRL, &value16);
+	if (error)
+		return;
+
+	value16 &= 0x7;
 
 	value16 |= _TXDMA_BEQ_MAP(beQ)	| _TXDMA_BKQ_MAP(bkQ) |
 		   _TXDMA_VIQ_MAP(viQ)	| _TXDMA_VOQ_MAP(voQ) |
@@ -868,7 +880,12 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	/*  Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
 	/*  */
 	/*  Enable MACTXEN/MACRXEN block */
-	value16 = rtw_read16(Adapter, REG_CR);
+	error = rtw_read16(Adapter, REG_CR, &value16);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
+
 	value16 |= (MACTXEN | MACRXEN);
 	rtw_write8(Adapter, REG_CR, value16);
 
@@ -937,6 +954,8 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 		Adapter->mppriv.channel = haldata->CurrentChannel;
 		MPT_InitializeAdapter(Adapter, Adapter->mppriv.channel);
 	} else {
+		u16 val16;
+
 		/*  2010/08/11 MH Merge from 8192SE for Minicard init. We need to confirm current radio status */
 		/*  and then decide to enable RF or not.!!!??? For Selective suspend mode. We may not */
 		/*  call initstruct adapter. May cause some problem?? */
@@ -956,7 +975,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 		rtw_write16(Adapter, REG_TX_RPT_TIME, 0x3DF0);
 
 		/* enable tx DMA to drop the redundate data of packet */
-		rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK) | DROP_DATA_EN));
+		error = rtw_read16(Adapter, REG_TXDMA_OFFSET_CHK, &val16);
+		if (error) {
+			status = _FAIL;
+			goto exit;
+		}
+
+		rtw_write16(Adapter, REG_TXDMA_OFFSET_CHK, (val16 | DROP_DATA_EN));
 
 		HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_IQK);
 		/*  2010/08/26 MH Merge from 8192CE. */
@@ -1982,7 +2007,9 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			rtw_write8(Adapter, REG_TXPAUSE, 0xff);
 
 			/* keep sn */
-			Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
+			error = rtw_read16(Adapter, REG_NQOS_SEQ, &Adapter->xmitpriv.nqos_ssn);
+			if (error)
+				return;
 
 			if (!pwrpriv->bkeepfwalive) {
 				/* RX DMA stop */
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index c4f114c3d571..f713ee4bdbc8 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -125,19 +125,33 @@ static int usb_read8(struct intf_hdl *pintfhdl, u32 addr, u8 *data)
 	return 0;
 }
 
-static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
 {
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
-	__le32 data;
+	int res;
+	__le32 tmp;
+
+	if (WARN_ON(unlikely(!data)))
+		return -EINVAL;
 
 	requesttype = 0x01;/* read_in */
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 2;
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
+	if (res < 0) {
+		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 16 bytes: %d\n", res);
+		return res;
+	} else if (res != len) {
+		dev_err(dvobj_to_dev(pintfhdl->pintf_dev),
+			"Failed to read 16 bytes, could read only %d bytes\n", res);
+		return -EIO;
+	}
 
-	return (u16)(le32_to_cpu(data) & 0xffff);
+	*data = le32_to_cpu(tmp) & 0xffff;
+
+	return 0;
 }
 
 static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 8e531d272927..2455dae6eebb 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -62,7 +62,7 @@ typedef void (*RT_WORKITEM_CALL_BACK)(void *pContext);
 
 int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
 
-u16 ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data);
 
 u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
 
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index fd99b36abca6..c44554c848cf 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -86,7 +86,7 @@ struct io_queue;
 
 struct _io_ops {
 	int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
-	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
+	int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
 	u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
 	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
 	int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
@@ -249,7 +249,7 @@ void _rtw_attrib_read(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 
 int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
-u16 _rtw_read16(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
 u32 _rtw_read32(struct adapter *adapter, u32 addr);
 void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
@@ -271,7 +271,7 @@ u32 _rtw_write_port_and_wait(struct adapter *adapter, u32 addr, u32 cnt,
 void _rtw_write_port_cancel(struct adapter *adapter);
 
 #define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
-#define rtw_read16(adapter, addr) _rtw_read16((adapter), (addr))
+#define rtw_read16(adapter, addr, data) _rtw_read16((adapter), (addr), (data))
 #define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
 #define rtw_read_mem(adapter, addr, cnt, mem)				\
 	_rtw_read_mem((adapter), (addr), (cnt), (mem))
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index c9f0772bcbe1..79f0fbaa841e 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2101,7 +2101,10 @@ static int rtw_wx_read32(struct net_device *dev,
 		sprintf(extra, "0x%02X", data32);
 		break;
 	case 2:
-		data32 = rtw_read16(padapter, addr);
+		error = rtw_read16(padapter, addr, (u16 *) &data32);
+		if (error)
+			return error;
+
 		sprintf(extra, "0x%04X", data32);
 		break;
 	case 4:
@@ -2271,7 +2274,8 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 					 (u8 *) &RegRWStruct->value);
 			break;
 		case 2:
-			RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
+			error = rtw_read16(padapter, RegRWStruct->offset,
+					  (u16 *) &RegRWStruct->value);
 			break;
 		case 4:
 			RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
@@ -3990,7 +3994,8 @@ static int rtw_dbg_port(struct net_device *dev,
 				DBG_88E("rtw_read8(0x%x) = 0x%02x\n", arg, (u8) tmp);
 			break;
 		case 2:
-			DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+			if (!rtw_read16(padapter, arg, (u16 *) &tmp))
+				DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
 			break;
 		case 4:
 			DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
@@ -4006,8 +4011,12 @@ static int rtw_dbg_port(struct net_device *dev,
 
 			break;
 		case 2:
+			error = rtw_read16(padapter, arg, (u16 *) &tmp);
+			if (error)
+				return error;
+
 			rtw_write16(padapter, arg, extra_arg);
-			DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, rtw_read16(padapter, arg));
+			DBG_88E("rtw_write16(0x%x) = 0x%04x\n", arg, (u16) tmp);
 			break;
 		case 4:
 			rtw_write32(padapter, arg, extra_arg);
@@ -4138,7 +4147,10 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read16(padapter, reg);
+			error = rtw_read16(padapter, reg, &final);
+			if (error)
+				return error;
+
 			if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
 			else
@@ -5387,7 +5399,11 @@ static int rtw_mp_read_reg(struct net_device *dev,
 		break;
 	case 'w':
 		/*  2 bytes */
-		sprintf(data, "%04x\n", rtw_read16(padapter, addr));
+		error = rtw_read16(padapter, addr, (u16 *) &val32);
+		if (error)
+			return error;
+
+		sprintf(data, "%04x\n", (u16) val32);
 		for (i = 0; i <= strlen(data); i++) {
 			if (i % 2 == 0) {
 				tmp[j] = ' ';
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
                                         ` (3 preceding siblings ...)
  2021-08-24  7:27                       ` [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16 Pavel Skripkin
@ 2021-08-24  7:27                       ` Pavel Skripkin
  2021-08-25  4:40                         ` Fabio M. De Francesco
  2021-08-26  8:51                         ` David Laight
  2021-08-24  7:27                       ` [PATCH v3 6/6] staging: r8188eu: make ReadEFuse return an int Pavel Skripkin
                                         ` (2 subsequent siblings)
  7 siblings, 2 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  7:27 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

_rtw_read32 function can fail in case of usb transfer failure. But
previous function prototype wasn't designed to return an error to
caller. It can cause a lot uninit value bugs all across the driver code,
since rtw_read32() returns local stack variable to caller.

Fix it by changing the prototype of this function. Now it returns an
int: 0 on success, negative error value on failure and callers should pass
the pointer to storage location for register value.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_debug.c      |  61 +++++++--
 drivers/staging/r8188eu/core/rtw_efuse.c      |  14 ++-
 drivers/staging/r8188eu/core/rtw_io.c         |   9 +-
 drivers/staging/r8188eu/core/rtw_mp.c         |  18 ++-
 drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |   4 +-
 drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   5 +-
 drivers/staging/r8188eu/core/rtw_sreset.c     |   9 +-
 .../r8188eu/hal/Hal8188ERateAdaptive.c        |   8 +-
 drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |   2 +-
 drivers/staging/r8188eu/hal/odm_interface.c   |   4 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   |  63 ++++++++--
 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  12 +-
 drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  14 ++-
 drivers/staging/r8188eu/hal/usb_halinit.c     | 119 +++++++++++++++---
 drivers/staging/r8188eu/hal/usb_ops_linux.c   |  22 +++-
 .../staging/r8188eu/include/odm_interface.h   |   2 +-
 drivers/staging/r8188eu/include/rtw_io.h      |   6 +-
 drivers/staging/r8188eu/os_dep/ioctl_linux.c  |  90 ++++++++-----
 18 files changed, 357 insertions(+), 105 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
index a41675e101ac..c76feb44ecfa 100644
--- a/drivers/staging/r8188eu/core/rtw_debug.c
+++ b/drivers/staging/r8188eu/core/rtw_debug.c
@@ -99,7 +99,12 @@ int proc_get_read_reg(char *page, char **start,
 				proc_get_read_addr, (u16) tmp);
 		break;
 	case 4:
-		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
+		error = rtw_read32(padapter, proc_get_read_addr, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n",
+				proc_get_read_addr, tmp);
 		break;
 	default:
 		len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
@@ -315,13 +320,20 @@ int proc_get_mac_reg_dump1(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 
 	for (i = 0x0; i < 0x300; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -338,13 +350,20 @@ int proc_get_mac_reg_dump2(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 	memset(page, 0, count);
 	for (i = 0x300; i < 0x600; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -361,13 +380,20 @@ int proc_get_mac_reg_dump3(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
 
 	for (i = 0x600; i < 0x800; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return error;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -384,12 +410,19 @@ int proc_get_bb_reg_dump1(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0x800; i < 0xB00; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -405,12 +438,19 @@ int proc_get_bb_reg_dump2(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0xB00; i < 0xE00; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
@@ -426,12 +466,19 @@ int proc_get_bb_reg_dump3(char *page, char **start,
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
 	int len = 0;
 	int i, j = 1;
+	int error;
+	u32 tmp;
 
 	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
 	for (i = 0xE00; i < 0x1000; i += 4) {
 		if (j % 4 == 1)
 			len += snprintf(page + len, count - len, "0x%02x", i);
-		len += snprintf(page + len, count - len, " 0x%08x ", rtw_read32(padapter, i));
+
+		error = rtw_read32(padapter, i, &tmp);
+		if (error)
+			return len;
+
+		len += snprintf(page + len, count - len, " 0x%08x ", tmp);
 		if ((j++) % 4 == 0)
 			len += snprintf(page + len, count - len, "\n");
 	}
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index b471f6446f78..dfe60bc6a547 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -183,9 +183,15 @@ ReadEFuseByte(
 
 	/* Check bit 32 read-ready */
 	retry = 0;
-	value32 = rtw_read32(Adapter, EFUSE_CTRL);
+	error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+	if (error)
+		return;
+
 	while (!(((value32 >> 24) & 0xff) & 0x80)  && (retry < 10000)) {
-		value32 = rtw_read32(Adapter, EFUSE_CTRL);
+		error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+		if (error)
+			return;
+
 		retry++;
 	}
 
@@ -194,7 +200,9 @@ ReadEFuseByte(
 	/*  Designer says that there shall be some delay after ready bit is set, or the */
 	/*  result will always stay on last data we read. */
 	udelay(50);
-	value32 = rtw_read32(Adapter, EFUSE_CTRL);
+	error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
+	if (error)
+		return;
 
 	*pbuf = (u8)(value32 & 0xff);
 }
diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
index fd64893c778d..df4d8ac8aadc 100644
--- a/drivers/staging/r8188eu/core/rtw_io.c
+++ b/drivers/staging/r8188eu/core/rtw_io.c
@@ -56,18 +56,15 @@ int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
 	return _read16(pintfhdl, addr, data);
 }
 
-u32 _rtw_read32(struct adapter *adapter, u32 addr)
+int __must_check _rtw_read32(struct adapter *adapter, u32 addr, u32 *data)
 {
-	u32 r_val;
 	struct io_priv *pio_priv = &adapter->iopriv;
 	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
-	u32	(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+	int	(*_read32)(struct intf_hdl *pintfhdl, u32 addr, u32 *data);
 
 	_read32 = pintfhdl->io_ops._read32;
 
-	r_val = _read32(pintfhdl, addr);
-
-	return r_val;
+	return _read32(pintfhdl, addr, data);
 }
 
 int _rtw_write8(struct adapter *adapter, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/core/rtw_mp.c b/drivers/staging/r8188eu/core/rtw_mp.c
index 76f0bc399819..e990e81966af 100644
--- a/drivers/staging/r8188eu/core/rtw_mp.c
+++ b/drivers/staging/r8188eu/core/rtw_mp.c
@@ -765,12 +765,17 @@ static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
 {
 	/* selection */
 	u32 phyrx_set = 0, count = 0;
+	int error;
 
 	phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
 	rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
 
 	/* Read packet count */
-	count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
+	error = rtw_read32(pAdapter, REG_RXERR_RPT, &count);
+	if (error)
+		return count;
+
+	count &= RXERR_COUNTER_MASK;
 
 	return count;
 }
@@ -803,8 +808,12 @@ u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
 static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
 {
 	int psd_val;
+	int error;
+
+	error = rtw_read32(pAdapter, 0x808, &psd_val);
+	if (error)
+		return 0;
 
-	psd_val = rtw_read32(pAdapter, 0x808);
 	psd_val &= 0xFFBFFC00;
 	psd_val |= point;
 
@@ -814,7 +823,10 @@ static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
 
 	rtw_write32(pAdapter, 0x808, psd_val);
 	mdelay(1);
-	psd_val = rtw_read32(pAdapter, 0x8B4);
+
+	error = rtw_read32(pAdapter, 0x8B4, &psd_val);
+	if (error)
+		return 0;
 
 	psd_val &= 0x0000FFFF;
 
diff --git a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
index c6f7636c2174..9eaef9c73516 100644
--- a/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
+++ b/drivers/staging/r8188eu/core/rtw_mp_ioctl.c
@@ -659,7 +659,9 @@ int rtl8188eu_oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv)
 		break;
 	default:
 		width = 4;
-		RegRWStruct->value = rtw_read32(Adapter, offset);
+		error = rtw_read32(Adapter, offset, &RegRWStruct->value);
+		if (error)
+			status = NDIS_STATUS_NOT_ACCEPTED;
 		break;
 	}
 
diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
index c3897b29121c..4335907acbc3 100644
--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
@@ -55,6 +55,7 @@ int ips_leave(struct adapter *padapter)
 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 	int result = _SUCCESS;
 	int keyid;
+	u32 tmp;
 
 	_enter_pwrlock(&pwrpriv->lock);
 
@@ -83,7 +84,9 @@ int ips_leave(struct adapter *padapter)
 			}
 		}
 
-		DBG_88E("==> ips_leave.....LED(0x%08x)...\n", rtw_read32(padapter, 0x4c));
+		if (!rtw_read32(padapter, 0x4c, &tmp))
+			DBG_88E("==> ips_leave.....LED(0x%08x)...\n", tmp);
+
 		pwrpriv->bips_processing = false;
 
 		pwrpriv->bkeepfwalive = false;
diff --git a/drivers/staging/r8188eu/core/rtw_sreset.c b/drivers/staging/r8188eu/core/rtw_sreset.c
index 8e1bc62e74e5..ec5d070e1641 100644
--- a/drivers/staging/r8188eu/core/rtw_sreset.c
+++ b/drivers/staging/r8188eu/core/rtw_sreset.c
@@ -29,13 +29,18 @@ u8 sreset_get_wifi_status(struct adapter *padapter)
 {
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+	int error;
 	u8 status = WIFI_STATUS_SUCCESS;
 	u32 val32 = 0;
 
 	if (psrtpriv->silent_reset_inprogress)
 		return status;
-	val32 = rtw_read32(padapter, REG_TXDMA_STATUS);
+	error = rtw_read32(padapter, REG_TXDMA_STATUS, &val32);
+	if (error) {
+		psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
+		return WIFI_MAC_TXDMA_ERROR;
+	}
+
 	if (val32 == 0xeaeaeaea) {
 		psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
 	} else if (val32 != 0) {
diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
index d873672feb27..bd4580eba0a9 100644
--- a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
+++ b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c
@@ -316,19 +316,19 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & 0x0000000d;
 		break;
 	case 12:
-		MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR0);
+		ODM_Read4Byte(dm_odm, REG_ARFR0, &MaskFromReg);
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
 		break;
 	case 13:
-		MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR1);
+		ODM_Read4Byte(dm_odm, REG_ARFR1, &MaskFromReg);
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
 		break;
 	case 14:
-		MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR2);
+		ODM_Read4Byte(dm_odm, REG_ARFR2, &MaskFromReg);
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
 		break;
 	case 15:
-		MaskFromReg = ODM_Read4Byte(dm_odm, REG_ARFR3);
+		ODM_Read4Byte(dm_odm, REG_ARFR3, &MaskFromReg);
 		pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg;
 		break;
 	default:
diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
index 3545ad60dc00..725a18dc3979 100644
--- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
+++ b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c
@@ -667,7 +667,7 @@ static void _PHY_SaveMACRegisters(
 		if (error)
 			return;
 	}
-	MACBackup[i] = ODM_Read4Byte(dm_odm, MACReg[i]);
+	ODM_Read4Byte(dm_odm, MACReg[i], MACBackup + i);
 }
 
 static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum)
diff --git a/drivers/staging/r8188eu/hal/odm_interface.c b/drivers/staging/r8188eu/hal/odm_interface.c
index 669d3e5eafb6..a47319dec231 100644
--- a/drivers/staging/r8188eu/hal/odm_interface.c
+++ b/drivers/staging/r8188eu/hal/odm_interface.c
@@ -16,10 +16,10 @@ int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data)
 	return rtw_read16(Adapter, RegAddr, data);
 }
 
-u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr)
+int ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 *data)
 {
 	struct adapter *Adapter = pDM_Odm->Adapter;
-	return rtw_read32(Adapter, RegAddr);
+	return rtw_read32(Adapter, RegAddr, data);
 }
 
 void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 94e2828c328e..69649a381727 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -254,8 +254,16 @@ static void efuse_read_phymap_from_txpktbuf(
 
 
 		/* data from EEPROM needs to be in LE */
-		lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
-		hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));
+		error = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, &lo32);
+		if (error)
+			return;
+		lo32 = cpu_to_le32(lo32);
+
+
+		error = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, &hi32);
+		if (error)
+			return;
+		hi32 = cpu_to_le32(hi32);
 
 		if (i == 0) {
 			/* Although lenc is only used in a debug statement,
@@ -375,6 +383,8 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 	u32 addr, rstatus, loop = 0;
 	u16 data_cnts = (data_len / 8) + 1;
 	u8 *pbuf = vzalloc(data_len + 10);
+	int error;
+
 	DBG_88E("###### %s ######\n", __func__);
 
 	rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
@@ -384,12 +394,25 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
 			rtw_usleep_os(2);
 			loop = 0;
 			do {
-				rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24));
+				error = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL, &reg_140);
+				if (error)
+					return;
+
+				reg_140 &= BIT(24);
+				rstatus = reg_140;
 				if (rstatus) {
-					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
+					error = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L,
+							  &fifo_data);
+					if (error)
+						return;
+
 					memcpy(pbuf + (addr * 8), &fifo_data, 4);
 
-					fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
+					error = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H,
+							  &fifo_data);
+					if (error)
+						return;
+
 					memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
 				}
 				rtw_usleep_os(2);
@@ -557,10 +580,14 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 {
 	u32	counter = 0;
 	u32	value32;
+	int error;
 
 	/*  polling CheckSum report */
 	do {
-		value32 = rtw_read32(padapter, REG_MCUFWDL);
+		error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+		if (error)
+			return _FAIL;
+
 		if (value32 & FWDL_ChkSum_rpt)
 			break;
 	} while (counter++ < POLLING_READY_TIMEOUT_COUNT);
@@ -571,7 +598,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 	}
 	DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
 
-	value32 = rtw_read32(padapter, REG_MCUFWDL);
+	error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+	if (error)
+		return _FAIL;
+
 	value32 |= MCUFWDL_RDY;
 	value32 &= ~WINTINI_RDY;
 	rtw_write32(padapter, REG_MCUFWDL, value32);
@@ -581,8 +611,10 @@ static s32 _FWFreeToGo(struct adapter *padapter)
 	/*  polling for FW ready */
 	counter = 0;
 	do {
-		value32 = rtw_read32(padapter, REG_MCUFWDL);
-		if (value32 & WINTINI_RDY) {
+		error = rtw_read32(padapter, REG_MCUFWDL, &value32);
+		if (error) {
+			return _FAIL;
+		} else if (value32 & WINTINI_RDY) {
 			DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
 			return _SUCCESS;
 		}
@@ -1765,12 +1797,16 @@ static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8
 static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
 {
 	u32				value32;
-	struct HAL_VERSION		ChipVersion;
+	struct HAL_VERSION		ChipVersion = {};
 	struct hal_data_8188e	*pHalData;
+	int error;
 
 	pHalData = GET_HAL_DATA(padapter);
 
-	value32 = rtw_read32(padapter, REG_SYS_CFG);
+	error = rtw_read32(padapter, REG_SYS_CFG, &value32);
+	if (error)
+		return ChipVersion;
+
 	ChipVersion.ICType = CHIP_8188E;
 	ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
 
@@ -1949,12 +1985,15 @@ static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
 	s32	count = 0;
 	u32	value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
 	u16	LLTReg = REG_LLT_INIT;
+	int error;
 
 	rtw_write32(padapter, LLTReg, value);
 
 	/* polling */
 	do {
-		value = rtw_read32(padapter, LLTReg);
+		error = rtw_read32(padapter, LLTReg, &value);
+		if (error)
+			return _FAIL;
 		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
 			break;
 
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
index 3afb66195413..24b2afb62d68 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c
@@ -75,8 +75,12 @@ rtl8188e_PHY_QueryBBReg(
 	)
 {
 	u32 ReturnValue = 0, OriginalValue, BitShift;
+	int error;
+
+	error = rtw_read32(Adapter, RegAddr, &OriginalValue);
+	if (error)
+		return ReturnValue;
 
-	OriginalValue = rtw_read32(Adapter, RegAddr);
 	BitShift = phy_CalculateBitShift(BitMask);
 	ReturnValue = (OriginalValue & BitMask) >> BitShift;
 	return ReturnValue;
@@ -103,9 +107,13 @@ rtl8188e_PHY_QueryBBReg(
 void rtl8188e_PHY_SetBBReg(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data)
 {
 	u32 OriginalValue, BitShift;
+	int error;
 
 	if (BitMask != bMaskDWord) { /* if not "double word" write */
-		OriginalValue = rtw_read32(Adapter, RegAddr);
+		error = rtw_read32(Adapter, RegAddr, &OriginalValue);
+		if (error)
+			return;
+
 		BitShift = phy_CalculateBitShift(BitMask);
 		Data = ((OriginalValue & (~BitMask)) | (Data << BitShift));
 	}
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
index 39dacfb23570..a023a0669ffd 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_sreset.c
@@ -14,14 +14,16 @@ void rtl8188e_sreset_xmit_status_check(struct adapter *padapter)
 {
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(padapter);
 	struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
+	int error;
 	unsigned long current_time;
 	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
 	unsigned int diff_time;
 	u32 txdma_status;
 
-	txdma_status = rtw_read32(padapter, REG_TXDMA_STATUS);
-	if (txdma_status != 0x00) {
+	error = rtw_read32(padapter, REG_TXDMA_STATUS, &txdma_status);
+	if (error) {
+		return;
+	} else if (txdma_status != 0x00) {
 		DBG_88E("%s REG_TXDMA_STATUS:0x%08x\n", __func__, txdma_status);
 		rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status);
 		rtl8188e_silentreset_for_specific_platform(padapter);
@@ -51,8 +53,10 @@ void rtl8188e_sreset_linked_status_check(struct adapter *padapter)
 	u8 fw_status = 0;
 	int error;
 
-	rx_dma_status = rtw_read32(padapter, REG_RXDMA_STATUS);
-	if (rx_dma_status != 0x00) {
+	error = rtw_read32(padapter, REG_RXDMA_STATUS, &rx_dma_status);
+	if (error) {
+		return;
+	} else if (rx_dma_status != 0x00) {
 		DBG_88E("%s REG_RXDMA_STATUS:0x%08x\n", __func__, rx_dma_status);
 		rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status);
 	}
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 4ecccc6499aa..3826476e3396 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -338,8 +338,12 @@ static void _InitQueuePriority(struct adapter *Adapter)
 static void _InitNetworkType(struct adapter *Adapter)
 {
 	u32 value32;
+	int error;
+
+	error = rtw_read32(Adapter, REG_CR, &value32);
+	if (error)
+		return;
 
-	value32 = rtw_read32(Adapter, REG_CR);
 	/*  TODO: use the other function to set network type */
 	value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
 
@@ -381,9 +385,13 @@ static void _InitAdaptiveCtrl(struct adapter *Adapter)
 {
 	u16 value16;
 	u32 value32;
+	int error;
 
 	/*  Response Rate Set */
-	value32 = rtw_read32(Adapter, REG_RRSR);
+	error = rtw_read32(Adapter, REG_RRSR, &value32);
+	if (error)
+		return;
+
 	value32 &= ~RATE_BITMAP_ALL;
 	value32 |= RATE_RRSR_CCK_ONLY_1M;
 	rtw_write32(Adapter, REG_RRSR, value32);
@@ -482,12 +490,16 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
 	u32 value32;
+	int error;
 
 	if (Adapter->registrypriv.wifi_spec)
 		haldata->UsbTxAggMode = false;
 
 	if (haldata->UsbTxAggMode) {
-		value32 = rtw_read32(Adapter, REG_TDECTRL);
+		error = rtw_read32(Adapter, REG_TDECTRL, &value32);
+		if (error)
+			return;
+
 		value32 = value32 & ~(BLK_DESC_NUM_MASK << BLK_DESC_NUM_SHIFT);
 		value32 |= ((haldata->UsbTxAggDescNum & BLK_DESC_NUM_MASK) << BLK_DESC_NUM_SHIFT);
 
@@ -671,12 +683,18 @@ enum {
 static void _InitAntenna_Selection(struct adapter *Adapter)
 {
 	struct hal_data_8188e	*haldata	= GET_HAL_DATA(Adapter);
+	u32 val32;
+	int error;
 
 	if (haldata->AntDivCfg == 0)
 		return;
 	DBG_88E("==>  %s ....\n", __func__);
 
-	rtw_write32(Adapter, REG_LEDCFG0, rtw_read32(Adapter, REG_LEDCFG0) | BIT(23));
+	error = rtw_read32(Adapter, REG_LEDCFG0, &val32);
+	if (error)
+		return;
+
+	rtw_write32(Adapter, REG_LEDCFG0, val32 | BIT(23));
 	PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, BIT(13), 0x01);
 
 	if (PHY_QueryBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, 0x300) == Antenna_A)
@@ -737,7 +755,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	u8 value8 = 0;
 	u16  value16;
 	u8 txpktbuf_bndy;
-	u32 status = _SUCCESS;
+	u32 status = _SUCCESS, val32;
 	struct hal_data_8188e		*haldata = GET_HAL_DATA(Adapter);
 	struct pwrctrl_priv		*pwrctrlpriv = &Adapter->pwrctrlpriv;
 	struct registry_priv	*pregistrypriv = &Adapter->registrypriv;
@@ -1007,7 +1025,13 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter)
 	rtw_write8(Adapter, REG_USB_HRPWM, 0);
 
 	/* ack for xmit mgmt frames. */
-	rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, rtw_read32(Adapter, REG_FWHW_TXQ_CTRL) | BIT(12));
+	error = rtw_read32(Adapter, REG_FWHW_TXQ_CTRL, &val32);
+	if (error) {
+		status = _FAIL;
+		goto exit;
+	}
+
+	rtw_write32(Adapter, REG_FWHW_TXQ_CTRL, val32 | BIT(12));
 
 exit:
 	HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_END);
@@ -1480,6 +1504,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
 	int error;
 	u8 tmp;
+	u32 val32;
 
 	switch (variable) {
 	case HW_VAR_MEDIA_STATUS:
@@ -1598,11 +1623,17 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		break;
 	case HW_VAR_CHECK_BSSID:
 		if (*((u8 *)val)) {
-			rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+			error = rtw_read32(Adapter, REG_RCR, &val32);
+			if (error)
+				return;
+
+			rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 		} else {
 			u32 val32;
 
-			val32 = rtw_read32(Adapter, REG_RCR);
+			error = rtw_read32(Adapter, REG_RCR, &val32);
+			if (error)
+				return;
 
 			val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 
@@ -1627,7 +1658,11 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	case HW_VAR_MLME_SITESURVEY:
 		if (*((u8 *)val)) { /* under sitesurvey */
 			/* config RCR to receive different BSSID & not to receive data frame */
-			u32 v = rtw_read32(Adapter, REG_RCR);
+			u32 v;
+
+			error = rtw_read32(Adapter, REG_RCR, &v);
+			if (error)
+				return;
 
 			v &= ~(RCR_CBSSID_BCN);
 			rtw_write32(Adapter, REG_RCR, v);
@@ -1661,14 +1696,27 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			}
 
 			if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
-				rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+				error = rtw_read32(Adapter, REG_RCR, &val32);
+				if (error)
+					return;
+
+				rtw_write32(Adapter, REG_RCR, val32 | RCR_CBSSID_BCN);
 			} else {
+				u32 v;
+
 				if (Adapter->in_cta_test) {
-					u32 v = rtw_read32(Adapter, REG_RCR);
+					error = rtw_read32(Adapter, REG_RCR, &v);
+					if (error)
+						return;
+
 					v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 					rtw_write32(Adapter, REG_RCR, v);
 				} else {
-					rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
+					error = rtw_read32(Adapter, REG_RCR, &v);
+					if (error)
+						return;
+
+					rtw_write32(Adapter, REG_RCR, v | RCR_CBSSID_BCN);
 				}
 			}
 		}
@@ -1679,17 +1727,26 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 			u8 type = *((u8 *)val);
 			u8 tmp;
 			struct mlme_priv	*pmlmepriv = &Adapter->mlmepriv;
+			u32 v;
 
 			if (type == 0) { /*  prepare to join */
 				/* enable to rx data frame.Accept all data frame */
 				rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
 
 				if (Adapter->in_cta_test) {
-					u32 v = rtw_read32(Adapter, REG_RCR);
+					error = rtw_read32(Adapter, REG_RCR, &v);
+					if (error)
+						return;
+
 					v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 					rtw_write32(Adapter, REG_RCR, v);
 				} else {
-					rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
+					error = rtw_read32(Adapter, REG_RCR, &v);
+					if (error)
+						return;
+
+					rtw_write32(Adapter, REG_RCR,
+						    v | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 				}
 
 				if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
@@ -2002,6 +2059,7 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		{
 			struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
 			u8 trycnt = 100;
+			u32 v;
 
 			/* pause tx */
 			rtw_write8(Adapter, REG_TXPAUSE, 0xff);
@@ -2013,9 +2071,18 @@ static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 
 			if (!pwrpriv->bkeepfwalive) {
 				/* RX DMA stop */
-				rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
+
+				error = rtw_read32(Adapter, REG_RXPKT_NUM, &v);
+				if (error)
+					return;
+
+				rtw_write32(Adapter, REG_RXPKT_NUM, (v | RW_RELEASE_EN));
 				do {
-					if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
+					error = rtw_read32(Adapter, REG_RXPKT_NUM, &v);
+					if (error)
+						return;
+
+					if (!(v & RXDMA_IDLE))
 						break;
 				} while (trycnt--);
 				if (trycnt == 0)
@@ -2066,6 +2133,7 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 	struct odm_dm_struct *podmpriv = &haldata->odmpriv;
 	int error;
 	u8 tmp;
+	u32 val32;
 
 	switch (variable) {
 	case HW_VAR_BASIC_RATE:
@@ -2097,7 +2165,13 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 				val[0] = true;
 			} else {
 				u32 valRCR;
-				valRCR = rtw_read32(Adapter, REG_RCR);
+
+				error = rtw_read32(Adapter, REG_RCR, &valRCR);
+				if (error) {
+					*val = false;
+					return;
+				}
+
 				valRCR &= 0x00070000;
 				if (valRCR)
 					val[0] = false;
@@ -2116,7 +2190,11 @@ static void GetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
 		*val = haldata->bMacPwrCtrlOn;
 		break;
 	case HW_VAR_CHK_HI_QUEUE_EMPTY:
-		*val = ((rtw_read32(Adapter, REG_HGQ_INFORMATION) & 0x0000ff00) == 0) ? true : false;
+		error = rtw_read32(Adapter, REG_HGQ_INFORMATION, &val32);
+		if (error || val32 & 0x0000ff00)
+			*val = false;
+		else
+			*val = true;
 		break;
 	default:
 		break;
@@ -2374,7 +2452,10 @@ static void SetBeaconRelatedRegisters8188EUsb(struct adapter *adapt)
 
 	rtw_write8(adapt, REG_SLOT, 0x09);
 
-	value32 = rtw_read32(adapt, REG_TCR);
+	error = rtw_read32(adapt, REG_TCR, &value32);
+	if (error)
+		return;
+
 	value32 &= ~TSFRST;
 	rtw_write32(adapt,  REG_TCR, value32);
 
diff --git a/drivers/staging/r8188eu/hal/usb_ops_linux.c b/drivers/staging/r8188eu/hal/usb_ops_linux.c
index f713ee4bdbc8..b82dd3e16200 100644
--- a/drivers/staging/r8188eu/hal/usb_ops_linux.c
+++ b/drivers/staging/r8188eu/hal/usb_ops_linux.c
@@ -154,21 +154,35 @@ static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
 	return 0;
 }
 
-static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
+static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
 {
 	u8 requesttype;
 	u16 wvalue;
 	u16 len;
-	__le32 data;
+	int res;
+	__le32 tmp;
+
+	if (WARN_ON(unlikely(!data)))
+		return -EINVAL;
 
 	requesttype = 0x01;/* read_in */
 
 	wvalue = (u16)(addr & 0x0000ffff);
 	len = 4;
 
-	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
+	res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
+	if (res < 0) {
+		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
+		return res;
+	} else if (res != len) {
+		dev_err(dvobj_to_dev(pintfhdl->pintf_dev),
+			"Failed to read 32 bytes, could read only %d bytes\n", res);
+		return -EIO;
+	}
+
+	*data = le32_to_cpu(tmp);
 
-	return le32_to_cpu(data);
+	return 0;
 }
 
 static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
diff --git a/drivers/staging/r8188eu/include/odm_interface.h b/drivers/staging/r8188eu/include/odm_interface.h
index 2455dae6eebb..bbb1045c9e7d 100644
--- a/drivers/staging/r8188eu/include/odm_interface.h
+++ b/drivers/staging/r8188eu/include/odm_interface.h
@@ -64,7 +64,7 @@ int ODM_Read1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 *data);
 
 int ODM_Read2Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u16 *data);
 
-u32 ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr);
+int ODM_Read4Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u32 *data);
 
 void ODM_Write1Byte(struct odm_dm_struct *pDM_Odm, u32 RegAddr, u8 Data);
 
diff --git a/drivers/staging/r8188eu/include/rtw_io.h b/drivers/staging/r8188eu/include/rtw_io.h
index c44554c848cf..501168457518 100644
--- a/drivers/staging/r8188eu/include/rtw_io.h
+++ b/drivers/staging/r8188eu/include/rtw_io.h
@@ -87,7 +87,7 @@ struct io_queue;
 struct _io_ops {
 	int (*_read8)(struct intf_hdl *pintfhdl, u32 addr, u8 *data);
 	int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
-	u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
+	int (*_read32)(struct intf_hdl *pintfhdl, u32 addr, u32 *data);
 	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
 	int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
 	int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
@@ -250,7 +250,7 @@ void _rtw_attrib_write(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 
 int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data);
 int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data);
-u32 _rtw_read32(struct adapter *adapter, u32 addr);
+int __must_check _rtw_read32(struct adapter *adapter, u32 addr, u32 *data);
 void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void _rtw_read_port_cancel(struct adapter *adapter);
@@ -272,7 +272,7 @@ void _rtw_write_port_cancel(struct adapter *adapter);
 
 #define rtw_read8(adapter, addr, data) _rtw_read8((adapter), (addr), (data))
 #define rtw_read16(adapter, addr, data) _rtw_read16((adapter), (addr), (data))
-#define rtw_read32(adapter, addr) _rtw_read32((adapter), (addr))
+#define rtw_read32(adapter, addr, data) _rtw_read32((adapter), (addr), (data))
 #define rtw_read_mem(adapter, addr, cnt, mem)				\
 	_rtw_read_mem((adapter), (addr), (cnt), (mem))
 #define rtw_read_port(adapter, addr, cnt, mem)				\
diff --git a/drivers/staging/r8188eu/os_dep/ioctl_linux.c b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
index 79f0fbaa841e..65b240d6c544 100644
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c
@@ -2108,7 +2108,10 @@ static int rtw_wx_read32(struct net_device *dev,
 		sprintf(extra, "0x%04X", data32);
 		break;
 	case 4:
-		data32 = rtw_read32(padapter, addr);
+		error = rtw_read32(padapter, addr, &data32);
+		if (error)
+			return error;
+
 		sprintf(extra, "0x%08X", data32);
 		break;
 	default:
@@ -2278,7 +2281,7 @@ static void rtw_dbg_mode_hdl(struct adapter *padapter, u32 id, u8 *pdata, u32 le
 					  (u16 *) &RegRWStruct->value);
 			break;
 		case 4:
-			RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
+			error = rtw_read32(padapter, RegRWStruct->offset, &RegRWStruct->value);
 			break;
 		default:
 			break;
@@ -3818,6 +3821,8 @@ static int rtw_cta_test_start(struct net_device *dev,
 {
 	int ret = 0;
 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
+	int error;
+
 	DBG_88E("%s %s\n", __func__, extra);
 	if (!strcmp(extra, "1"))
 		padapter->in_cta_test = 1;
@@ -3825,12 +3830,22 @@ static int rtw_cta_test_start(struct net_device *dev,
 		padapter->in_cta_test = 0;
 
 	if (padapter->in_cta_test) {
-		u32 v = rtw_read32(padapter, REG_RCR);
+		u32 v;
+
+		error = rtw_read32(padapter, REG_RCR, &v);
+		if (error)
+			return error;
+
 		v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
 		rtw_write32(padapter, REG_RCR, v);
 		DBG_88E("enable RCR_ADF\n");
 	} else {
-		u32 v = rtw_read32(padapter, REG_RCR);
+		u32 v;
+
+		error = rtw_read32(padapter, REG_RCR, &v);
+		if (error)
+			return error;
+
 		v |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;/*  RCR_ADF */
 		rtw_write32(padapter, REG_RCR, v);
 		DBG_88E("disable RCR_ADF\n");
@@ -3900,18 +3915,23 @@ static int rtw_rereg_nd_name(struct net_device *dev,
 static void mac_reg_dump(struct adapter *padapter)
 {
 	int i, j = 1;
+
 	pr_info("\n ======= MAC REG =======\n");
 	for (i = 0x0; i < 0x300; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+		DBG_88E_REG32(" 0x%08x ", padapter, i);
+
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
 	for (i = 0x400; i < 0x800; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+
+		DBG_88E_REG32(" 0x%08x ", padapter, i);
+
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
@@ -3920,12 +3940,14 @@ static void mac_reg_dump(struct adapter *padapter)
 static void bb_reg_dump(struct adapter *padapter)
 {
 	int i, j = 1;
+
 	pr_info("\n ======= BB REG =======\n");
 	for (i = 0x800; i < 0x1000; i += 4) {
 		if (j % 4 == 1)
 			pr_info("0x%02x", i);
 
-		pr_info(" 0x%08x ", rtw_read32(padapter, i));
+		DBG_88E_REG32(" 0x%08x ", padapter, i);
+
 		if ((j++) % 4 == 0)
 			pr_info("\n");
 	}
@@ -3998,7 +4020,8 @@ static int rtw_dbg_port(struct net_device *dev,
 				DBG_88E("rtw_read16(0x%x) = 0x%04x\n", arg, (u16) tmp);
 			break;
 		case 4:
-			DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+			if (!rtw_read32(padapter, arg, &val32))
+				DBG_88E("rtw_read32(0x%x) = 0x%08x\n", arg, val32);
 			break;
 		}
 		break;
@@ -4020,7 +4043,9 @@ static int rtw_dbg_port(struct net_device *dev,
 			break;
 		case 4:
 			rtw_write32(padapter, arg, extra_arg);
-			DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, rtw_read32(padapter, arg));
+
+			if (!rtw_read32(padapter, arg, &val32))
+				DBG_88E("rtw_write32(0x%x) = 0x%08x\n", arg, val32);
 			break;
 		}
 		break;
@@ -4178,7 +4203,10 @@ static int rtw_dbg_port(struct net_device *dev,
 			if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
 				ret = -EPERM;
 
-			final = rtw_read32(padapter, reg);
+			error = rtw_read32(padapter, reg, &final);
+			if (error)
+				break;
+
 			if (start_value + write_num - 1 == final)
 				DBG_88E("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n",
 					reg, write_num, start_value, final);
@@ -4460,30 +4488,30 @@ static int rtw_dbg_port(struct net_device *dev,
 			DBG_88E_REG8("rd(0xc58) = 0x%x\n", padapter, 0xc58);
 			break;
 		case 0xff:
-			DBG_88E("dbg(0x210) = 0x%x\n", rtw_read32(padapter, 0x210));
-			DBG_88E("dbg(0x608) = 0x%x\n", rtw_read32(padapter, 0x608));
-			DBG_88E("dbg(0x280) = 0x%x\n", rtw_read32(padapter, 0x280));
-			DBG_88E("dbg(0x284) = 0x%x\n", rtw_read32(padapter, 0x284));
-			DBG_88E("dbg(0x288) = 0x%x\n", rtw_read32(padapter, 0x288));
+			DBG_88E_REG32("dbg(0x210) = 0x%x\n", padapter, 0x210);
+			DBG_88E_REG32("dbg(0x608) = 0x%x\n", padapter, 0x608);
+			DBG_88E_REG32("dbg(0x280) = 0x%x\n", padapter, 0x280);
+			DBG_88E_REG32("dbg(0x284) = 0x%x\n", padapter, 0x284);
+			DBG_88E_REG32("dbg(0x288) = 0x%x\n", padapter, 0x288);
 
-			DBG_88E("dbg(0x664) = 0x%x\n", rtw_read32(padapter, 0x664));
+			DBG_88E_REG32("dbg(0x664) = 0x%x\n", padapter, 0x664);
 
 			DBG_88E("\n");
 
-			DBG_88E("dbg(0x430) = 0x%x\n", rtw_read32(padapter, 0x430));
-			DBG_88E("dbg(0x438) = 0x%x\n", rtw_read32(padapter, 0x438));
+			DBG_88E_REG32("dbg(0x430) = 0x%x\n", padapter, 0x430);
+			DBG_88E_REG32("dbg(0x438) = 0x%x\n", padapter, 0x438);
 
-			DBG_88E("dbg(0x440) = 0x%x\n", rtw_read32(padapter, 0x440));
+			DBG_88E_REG32("dbg(0x440) = 0x%x\n", padapter, 0x440);
 
-			DBG_88E("dbg(0x458) = 0x%x\n", rtw_read32(padapter, 0x458));
+			DBG_88E_REG32("dbg(0x458) = 0x%x\n", padapter, 0x458);
 
-			DBG_88E("dbg(0x484) = 0x%x\n", rtw_read32(padapter, 0x484));
-			DBG_88E("dbg(0x488) = 0x%x\n", rtw_read32(padapter, 0x488));
+			DBG_88E_REG32("dbg(0x484) = 0x%x\n", padapter, 0x484);
+			DBG_88E_REG32("dbg(0x488) = 0x%x\n", padapter, 0x488);
 
-			DBG_88E("dbg(0x444) = 0x%x\n", rtw_read32(padapter, 0x444));
-			DBG_88E("dbg(0x448) = 0x%x\n", rtw_read32(padapter, 0x448));
-			DBG_88E("dbg(0x44c) = 0x%x\n", rtw_read32(padapter, 0x44c));
-			DBG_88E("dbg(0x450) = 0x%x\n", rtw_read32(padapter, 0x450));
+			DBG_88E_REG32("dbg(0x444) = 0x%x\n", padapter, 0x444);
+			DBG_88E_REG32("dbg(0x448) = 0x%x\n", padapter, 0x448);
+			DBG_88E_REG32("dbg(0x44c) = 0x%x\n", padapter, 0x44c);
+			DBG_88E_REG32("dbg(0x450) = 0x%x\n", padapter, 0x450);
 			break;
 		}
 		break;
@@ -5434,7 +5462,11 @@ static int rtw_mp_read_reg(struct net_device *dev,
 		break;
 	case 'd':
 		/*  4 bytes */
-		sprintf(data, "%08x", rtw_read32(padapter, addr));
+		error = rtw_read32(padapter, addr, &val32);
+		if (error)
+			return error;
+
+		sprintf(data, "%08x", val32);
 		/* add read data format blank */
 		for (i = 0; i <= strlen(data); i++) {
 			if (i % 2 == 0) {
@@ -6154,14 +6186,14 @@ static int rtw_mp_dump(struct net_device *dev,
 		for (i = 0x0; i < 0x300; i += 4) {
 			if (j % 4 == 1)
 				DBG_88E("0x%02x", i);
-			DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+			DBG_88E_REG32(" 0x%08x ", padapter, i);
 			if ((j++) % 4 == 0)
 				DBG_88E("\n");
 		}
 		for (i = 0x400; i < 0x1000; i += 4) {
 			if (j % 4 == 1)
 				DBG_88E("0x%02x", i);
-			DBG_88E(" 0x%08x ", rtw_read32(padapter, i));
+			DBG_88E_REG32(" 0x%08x ", padapter, i);
 			if ((j++) % 4 == 0)
 				DBG_88E("\n");
 		}
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* [PATCH v3 6/6] staging: r8188eu: make ReadEFuse return an int
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
                                         ` (4 preceding siblings ...)
  2021-08-24  7:27                       ` [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32 Pavel Skripkin
@ 2021-08-24  7:27                       ` Pavel Skripkin
  2021-08-25 10:13                       ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Fabio M. De Francesco
  2021-08-27  7:49                       ` Kari Argillander
  7 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  7:27 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel, Pavel Skripkin

ReadEFuse can fail in case of _rtw_read() failure. Callers should
handle this error to avoid uninit value bugs, since ReadEFuse
won't initialized passed pbuf in case of usb transfer failure.

To achieve it, ReadEFuseByte() now returns an int and all callers of
ReadEFuseByte() passes error code up to calltrace to rtw_usb_if1_init(),
which fails when reading regiters fails.

Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/staging/r8188eu/core/rtw_efuse.c      | 45 ++++++++-----
 drivers/staging/r8188eu/hal/hal_intf.c        |  6 +-
 .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 65 ++++++++++++-------
 drivers/staging/r8188eu/hal/usb_halinit.c     | 18 +++--
 drivers/staging/r8188eu/include/hal_intf.h    |  6 +-
 .../staging/r8188eu/include/rtl8188e_hal.h    |  2 +-
 drivers/staging/r8188eu/include/rtw_efuse.h   |  4 +-
 drivers/staging/r8188eu/os_dep/usb_intf.c     |  3 +-
 8 files changed, 96 insertions(+), 53 deletions(-)

diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c
index dfe60bc6a547..5bfcf80b2678 100644
--- a/drivers/staging/r8188eu/core/rtw_efuse.c
+++ b/drivers/staging/r8188eu/core/rtw_efuse.c
@@ -149,7 +149,7 @@ Efuse_CalculateWordCnts(u8 word_en)
 /*  */
 /* 	Created by Roger, 2008.10.21. */
 /*  */
-void
+int
 ReadEFuseByte(
 		struct adapter *Adapter,
 		u16 _offset,
@@ -163,21 +163,21 @@ ReadEFuseByte(
 
 	if (pseudo) {
 		Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
-		return;
+		return 0;
 	}
 
 	/* Write Address */
 	rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff));
 	error = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte);
 	if (error)
-		return;
+		return error;
 
 	rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
 
 	/* Write bit 32 0 */
 	error = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte);
 	if (error)
-		return;
+		return error;
 
 	rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
 
@@ -185,12 +185,12 @@ ReadEFuseByte(
 	retry = 0;
 	error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
 	if (error)
-		return;
+		return error;
 
 	while (!(((value32 >> 24) & 0xff) & 0x80)  && (retry < 10000)) {
 		error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
 		if (error)
-			return;
+			return error;
 
 		retry++;
 	}
@@ -202,9 +202,11 @@ ReadEFuseByte(
 	udelay(50);
 	error = rtw_read32(Adapter, EFUSE_CTRL, &value32);
 	if (error)
-		return;
+		return error;
 
 	*pbuf = (u8)(value32 & 0xff);
+
+	return 0;
 }
 
 /*  */
@@ -225,9 +227,9 @@ ReadEFuseByte(
 /* 					write addr must be after sec5. */
 /*  */
 
-static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
+static int efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo)
 {
-	Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
+	return Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo);
 }
 
 void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo
@@ -538,6 +540,7 @@ u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size)
 u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 {
 	u16 mapLen = 0;
+	int error;
 
 	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
 
@@ -546,7 +549,9 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 
 	Efuse_PowerSwitch(padapter, false, true);
 
-	efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+	error = efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false);
+	if (error)
+		return _FAIL;
 
 	Efuse_PowerSwitch(padapter, false, false);
 
@@ -556,6 +561,7 @@ u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 {
 	u16 mapLen = 0;
+	int error;
 
 	EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false);
 
@@ -564,7 +570,9 @@ u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 
 	Efuse_PowerSwitch(padapter, false, true);
 
-	efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+	error = efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false);
+	if (error)
+		return _FAIL;
 
 	Efuse_PowerSwitch(padapter, false, false);
 
@@ -835,17 +843,22 @@ efuse_ShadowRead4Byte(
  * 11/11/2008	MHC		Create Version 0.
  *
  *---------------------------------------------------------------------------*/
-static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
+static int Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo)
 {
 	u16 mapLen = 0;
+	int error;
 
 	Efuse_PowerSwitch(pAdapter, false, true);
 
 	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo);
 
-	efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+	error = efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo);
+	if (error)
+		return error;
 
 	Efuse_PowerSwitch(pAdapter, false, false);
+
+	return 0;
 }
 
 /*-----------------------------------------------------------------------------
@@ -864,7 +877,7 @@ static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse,
  * 11/13/2008	MHC		Create Version 0.
  *
  *---------------------------------------------------------------------------*/
-void EFUSE_ShadowMapUpdate(
+int EFUSE_ShadowMapUpdate(
 	struct adapter *pAdapter,
 	u8 efuseType,
 	bool pseudo)
@@ -877,7 +890,9 @@ void EFUSE_ShadowMapUpdate(
 	if (pEEPROM->bautoload_fail_flag)
 		memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
 	else
-		Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+		return Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo);
+
+	return 0;
 } /*  EFUSE_ShadowMapUpdate */
 
 /*-----------------------------------------------------------------------------
diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c
index a6d589e89aeb..dce9a58eaf6f 100644
--- a/drivers/staging/r8188eu/hal/hal_intf.c
+++ b/drivers/staging/r8188eu/hal/hal_intf.c
@@ -12,10 +12,12 @@ void rtw_hal_chip_configure(struct adapter *adapt)
 		adapt->HalFunc.intf_chip_configure(adapt);
 }
 
-void rtw_hal_read_chip_info(struct adapter *adapt)
+int rtw_hal_read_chip_info(struct adapter *adapt)
 {
 	if (adapt->HalFunc.read_adapter_info)
-		adapt->HalFunc.read_adapter_info(adapt);
+		return adapt->HalFunc.read_adapter_info(adapt);
+
+	return _FAIL;
 }
 
 void rtw_hal_read_chip_version(struct adapter *adapt)
diff --git a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
index 69649a381727..41cf432398e2 100644
--- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c
@@ -871,7 +871,7 @@ rtl8188e_EfusePowerSwitch(
 	hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
 }
 
-static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
+static int Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	u16			_offset,
 	u16			_size_byte,
 	u8 *pbuf,
@@ -886,24 +886,26 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	u16	**eFuseWord = NULL;
 	u16	efuse_utilized = 0;
 	u8 u1temp = 0;
+	int error = 0;
 
 	/*  */
 	/*  Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
 	/*  */
 	if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {/*  total E-Fuse table is 512bytes */
 		DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
-		goto exit;
+		return -EINVAL;
 	}
 
 	efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
 	if (!efuseTbl) {
 		DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
-		goto exit;
+		return -ENOMEM;
 	}
 
 	eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
 	if (!eFuseWord) {
 		DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
+		error = -ENOMEM;
 		goto exit;
 	}
 
@@ -916,12 +918,16 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 	/*  1. Read the first byte to check if efuse is empty!!! */
 	/*  */
 	/*  */
-	ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+	error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+	if (error)
+		goto exit;
+
 	if (*rtemp8 != 0xFF) {
 		efuse_utilized++;
 		eFuse_Addr++;
 	} else {
 		DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
+		error = -EAGAIN;
 		goto exit;
 	}
 
@@ -933,11 +939,15 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 		if ((*rtemp8 & 0x1F) == 0x0F) {		/* extended header */
 			u1temp = ((*rtemp8 & 0xE0) >> 5);
 
-			ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+			error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+			if (error)
+				goto exit;
 
 			if ((*rtemp8 & 0x0F) == 0x0F) {
 				eFuse_Addr++;
-				ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+				error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+				if (error)
+					goto exit;
 
 				if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
 					eFuse_Addr++;
@@ -958,13 +968,19 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
 				/*  Check word enable condition in the section */
 				if (!(wren & 0x01)) {
-					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					if (error)
+						goto exit;
+
 					eFuse_Addr++;
 					efuse_utilized++;
 					eFuseWord[offset][i] = (*rtemp8 & 0xff);
 					if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
 						break;
-					ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+					if (error)
+						goto exit;
+
 					eFuse_Addr++;
 					efuse_utilized++;
 					eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
@@ -976,7 +992,9 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 		}
 
 		/*  Read next PG header */
-		ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+		error = ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
+		if (error)
+			goto exit;
 
 		if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
 			efuse_utilized++;
@@ -1002,9 +1020,11 @@ static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
 exit:
 	kfree(efuseTbl);
 	kfree(eFuseWord);
+
+	return error;
 }
 
-static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
 {
 	if (!bPseudoTest) {
 		int ret = _FAIL;
@@ -1016,28 +1036,25 @@ static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u1
 			iol_mode_enable(Adapter, 0);
 
 			if (_SUCCESS == ret)
-				goto exit;
+				return 0;
 		}
 	}
-	Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
-
-exit:
-	return;
+	return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
 }
 
-static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
+static int ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
 {
-	Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
+	return Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
 }
 
-static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
+static int rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
 			       u16 _offset, u16 _size_byte, u8 *pbuf,
 			       bool bPseudoTest)
 {
 	if (bPseudoTest)
-		ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+		return ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
 	else
-		ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
+		return ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
 }
 
 /* Do not support BT */
@@ -2045,7 +2062,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
 	return status;
 }
 
-void
+int
 Hal_InitPGData88E(struct adapter *padapter)
 {
 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
@@ -2053,13 +2070,15 @@ Hal_InitPGData88E(struct adapter *padapter)
 	if (!pEEPROM->bautoload_fail_flag) { /*  autoload OK. */
 		if (!is_boot_from_eeprom(padapter)) {
 			/*  Read EFUSE real map to shadow. */
-			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+			return EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
 		}
 	} else {/* autoload fail */
 		/* update to default value 0xFF */
 		if (!is_boot_from_eeprom(padapter))
-			EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
+			return EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
 	}
+
+	return 0;
 }
 
 void
diff --git a/drivers/staging/r8188eu/hal/usb_halinit.c b/drivers/staging/r8188eu/hal/usb_halinit.c
index 3826476e3396..687baf4d9d97 100644
--- a/drivers/staging/r8188eu/hal/usb_halinit.c
+++ b/drivers/staging/r8188eu/hal/usb_halinit.c
@@ -1296,7 +1296,7 @@ readAdapterInfo_8188EU(
 	_ReadLEDSetting(adapt, eeprom->efuse_eeprom_data, eeprom->bautoload_fail_flag);
 }
 
-static void _ReadPROMContent(
+static int _ReadPROMContent(
 	struct adapter *Adapter
 	)
 {
@@ -1307,7 +1307,7 @@ static void _ReadPROMContent(
 	/* check system boot selection */
 	error = rtw_read8(Adapter, REG_9346CR, &eeValue);
 	if (error)
-		return;
+		return error;
 
 	eeprom->EepromOrEfuse		= (eeValue & BOOT_FROM_EEPROM) ? true : false;
 	eeprom->bautoload_fail_flag	= (eeValue & EEPROM_EN) ? false : true;
@@ -1315,8 +1315,13 @@ static void _ReadPROMContent(
 	DBG_88E("Boot from %s, Autoload %s !\n", (eeprom->EepromOrEfuse ? "EEPROM" : "EFUSE"),
 		(eeprom->bautoload_fail_flag ? "Fail" : "OK"));
 
-	Hal_InitPGData88E(Adapter);
+	error = Hal_InitPGData88E(Adapter);
+	if (error)
+		return error;
+
 	readAdapterInfo_8188EU(Adapter);
+
+	return 0;
 }
 
 static void _ReadRFType(struct adapter *Adapter)
@@ -1333,19 +1338,20 @@ static int _ReadAdapterInfo8188EU(struct adapter *Adapter)
 	MSG_88E("====> %s\n", __func__);
 
 	_ReadRFType(Adapter);/* rf_chip -> _InitRFType() */
-	_ReadPROMContent(Adapter);
+	if (_ReadPROMContent(Adapter))
+		return _FAIL;
 
 	MSG_88E("<==== %s in %d ms\n", __func__, rtw_get_passing_time_ms(start));
 
 	return _SUCCESS;
 }
 
-static void ReadAdapterInfo8188EU(struct adapter *Adapter)
+static int ReadAdapterInfo8188EU(struct adapter *Adapter)
 {
 	/*  Read EEPROM size before call any EEPROM function */
 	Adapter->EepromAddressSize = GetEEPROMSize8188E(Adapter);
 
-	_ReadAdapterInfo8188EU(Adapter);
+	return _ReadAdapterInfo8188EU(Adapter);
 }
 
 #define GPIO_DEBUG_PORT_NUM 0
diff --git a/drivers/staging/r8188eu/include/hal_intf.h b/drivers/staging/r8188eu/include/hal_intf.h
index fa252540e596..9241af39e3a3 100644
--- a/drivers/staging/r8188eu/include/hal_intf.h
+++ b/drivers/staging/r8188eu/include/hal_intf.h
@@ -154,7 +154,7 @@ struct hal_ops {
 
 	void	(*intf_chip_configure)(struct adapter *padapter);
 
-	void	(*read_adapter_info)(struct adapter *padapter);
+	int	(*read_adapter_info)(struct adapter *padapter);
 
 	void	(*enable_interrupt)(struct adapter *padapter);
 	void	(*disable_interrupt)(struct adapter *padapter);
@@ -222,7 +222,7 @@ struct hal_ops {
 
 	void (*EfusePowerSwitch)(struct adapter *padapter, u8 bWrite,
 				 u8 PwrState);
-	void (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
+	int (*ReadEFuse)(struct adapter *padapter, u8 efuseType, u16 _offset,
 			  u16 _size_byte, u8 *pbuf, bool bPseudoTest);
 	void (*EFUSEGetEfuseDefinition)(struct adapter *padapter, u8 efuseType,
 					u8 type, void *pOut, bool bPseudoTest);
@@ -324,7 +324,7 @@ void rtw_hal_set_hwreg(struct adapter *padapter, u8 variable, u8 *val);
 void rtw_hal_get_hwreg(struct adapter *padapter, u8 variable, u8 *val);
 
 void rtw_hal_chip_configure(struct adapter *padapter);
-void rtw_hal_read_chip_info(struct adapter *padapter);
+int rtw_hal_read_chip_info(struct adapter *padapter);
 void rtw_hal_read_chip_version(struct adapter *padapter);
 
 u8 rtw_hal_set_def_var(struct adapter *padapter,
diff --git a/drivers/staging/r8188eu/include/rtl8188e_hal.h b/drivers/staging/r8188eu/include/rtl8188e_hal.h
index 3939bf053de1..db9adbd0b024 100644
--- a/drivers/staging/r8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/r8188eu/include/rtl8188e_hal.h
@@ -410,7 +410,7 @@ s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
 
 /*  EFuse */
 u8 GetEEPROMSize8188E(struct adapter *padapter);
-void Hal_InitPGData88E(struct adapter *padapter);
+int Hal_InitPGData88E(struct adapter *padapter);
 void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
 void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
 			    bool AutoLoadFail);
diff --git a/drivers/staging/r8188eu/include/rtw_efuse.h b/drivers/staging/r8188eu/include/rtw_efuse.h
index b3ff46db2091..9657b66679e3 100644
--- a/drivers/staging/r8188eu/include/rtw_efuse.h
+++ b/drivers/staging/r8188eu/include/rtw_efuse.h
@@ -113,7 +113,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *adapter, u16 addr,
 			  u16 cnts, u8 *data);
 u16 Efuse_GetCurrentSize(struct adapter *adapter, u8 efusetype, bool test);
 u8 Efuse_CalculateWordCnts(u8 word_en);
-void ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
+int ReadEFuseByte(struct adapter *adapter, u16 _offset, u8 *pbuf, bool test);
 void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1,
 			      void *out, bool bPseudoTest);
 u8 efuse_OneByteRead(struct adapter *adapter, u16 addr, u8 *data, bool test);
@@ -128,7 +128,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *adapter, u16 efuse_addr,
 			     u8 word_en, u8 *data, bool test);
 
 u8 EFUSE_Read1Byte(struct adapter *adapter, u16 address);
-void EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
+int EFUSE_ShadowMapUpdate(struct adapter *adapter, u8 efusetype, bool test);
 void EFUSE_ShadowRead(struct adapter *adapt, u8 type, u16 offset, u32 *val);
 
 #endif
diff --git a/drivers/staging/r8188eu/os_dep/usb_intf.c b/drivers/staging/r8188eu/os_dep/usb_intf.c
index e002070f7fba..7a1a296f66b5 100644
--- a/drivers/staging/r8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/r8188eu/os_dep/usb_intf.c
@@ -608,7 +608,8 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
 	rtw_hal_chip_configure(padapter);
 
 	/* step read efuse/eeprom data and get mac_addr */
-	rtw_hal_read_chip_info(padapter);
+	if (rtw_hal_read_chip_info(padapter) == _FAIL)
+		goto free_hal_data;
 
 	/* step 5. */
 	if (rtw_init_drv_sw(padapter) == _FAIL)
-- 
2.32.0


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  6:40                       ` Pavel Skripkin
@ 2021-08-24  8:38                         ` Fabio M. De Francesco
  2021-08-24  8:47                           ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-24  8:38 UTC (permalink / raw)
  To: Phillip Potter, Pavel Skripkin
  Cc: Larry Finger, Greg KH, Michael Straube,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >> >  {
> >> >         u8 requesttype;
> >> >         u16 wvalue;
> >> >         u16 len;
> >> > -       __le32 data;
> >> > +       int res;
> >> > +       __le32 tmp;
> >> > +
> >> > +       if (WARN_ON(unlikely(!data)))
> >> > +               return -EINVAL;
> >> >
> >> >         requesttype = 0x01;/* read_in */
> >> >
> >> >         wvalue = (u16)(addr & 0x0000ffff);
> >> >         len = 4;
> >> >
> >> > -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> > +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> > +       if (res < 0) {
> >> > +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> >> > +       } else {
> >> > +               /* Noone cares about positive return value */
> >> > +               *data = le32_to_cpu(tmp);
> >> > +               res = 0;
> >> > +       }
> >> >
> >> > -       return le32_to_cpu(data);
> >> > +       return res;
> >> >  }
> >> 
> >> Dear Pavel,
> >> 
> >> OK, found the issue with decoded stack trace after reviewing this
> >> usb_read32 function. Your line:
> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> 
> >> should read:
> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> > 
> > Dear Philip,
> > 
> > No, it should read:
> > 
> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
> > 
> > I suspect that Pavel didn't notice he was reusing a line of the old code
> > wth no due changes.
> > 
> >> With this change, the driver runs fine with no crashes/oopses. I will
> >> explain the issue but you can probably see already, so I hope I'm not
> >> coming across as patronising, just trying to be helpful :-)
> >> 
> >> Essentially, you are taking the address of the data function parameter
> >> on this line with &data, a pointer to u32, which is giving you a
> >> pointer to a pointer to u32 (u32 **) for this function parameter
> >> variable. When passed to usbctrl_vendorreq, it is being passed to
> >> memcpy inside this function as a void *, meaning that memcpy
> >> subsequently overwrites the value of the memory address inside data to
> >> point to a different location, which is problem when it is later
> >> deferenced at:
> >> *data = le32_to_cpu(tmp);
> >> causing the OOPS
> >> 
> >> Also, as written, you can probably see that tmp is uninitialised. This
> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
> >> with that small change, usbctrl_vendorreq reads into tmp, which is
> >> then passed to le32_to_cpu whose return value is stored via the
> >> deferenced data ptr (which now has its original address within and not
> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
> >> series if you want to resend this patch. Many thanks.
> > 
> > I think that another typo is having 'tmp', because that variable is unnecessary
> > and "*data = le32_to_cpu(tmp);" is wrong too.
> > 
> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
> > I had read yesterday) is the only correct function of the three usb_read*().
> > 
> 
> Hi, guys!
> 
> 
> Sorry for breaking your system, Phillip. This code was part of "last 
> minute" changes and yes, it's broken :)
> 
> I get what Phillip said, because I _should_ read into tmp variable 
> instead of directly to data, but I don't get Fabio's idea, sorry.

Hi Pavel,

I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
with le32_to_cpu().

I simply thought that data could be passed to usbctrl_vendorreq as it-is.

> Data from chip comes in little-endian, so we _should_ convert it to 
> cpu's endian. Temp variable is needed to make smatch and all other 
> static anylis tools happy about this code.

Now that you explained that "Data from chip comes in little-endian", obviously 
I must agree with you that the code needs tmp and that tmp must be 
swapped by le32_to_cpu(), ahead of assigning it to *data.

Just a curiosity... Since I was not able to see that *data is returned in little endian,
can you please point me where in the code you found out that it is? There must
be some place in the code that I'm unable to find and see that *data is LE. 

Thanks in advance,

Fabio 
> 
> If I am missing something, please, let me know :) v3 is on the way...
> 
> With regards,
> Pavel Skripkin
> 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  8:38                         ` Fabio M. De Francesco
@ 2021-08-24  8:47                           ` Pavel Skripkin
  2021-08-24  8:53                             ` Pavel Skripkin
  2021-08-24 22:07                             ` Phillip Potter
  0 siblings, 2 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  8:47 UTC (permalink / raw)
  To: Fabio M. De Francesco, Phillip Potter
  Cc: Larry Finger, Greg KH, Michael Straube,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
> On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
>> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
>> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
>> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
>> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>> >> >  {
>> >> >         u8 requesttype;
>> >> >         u16 wvalue;
>> >> >         u16 len;
>> >> > -       __le32 data;
>> >> > +       int res;
>> >> > +       __le32 tmp;
>> >> > +
>> >> > +       if (WARN_ON(unlikely(!data)))
>> >> > +               return -EINVAL;
>> >> >
>> >> >         requesttype = 0x01;/* read_in */
>> >> >
>> >> >         wvalue = (u16)(addr & 0x0000ffff);
>> >> >         len = 4;
>> >> >
>> >> > -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> >> > +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> >> > +       if (res < 0) {
>> >> > +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>> >> > +       } else {
>> >> > +               /* Noone cares about positive return value */
>> >> > +               *data = le32_to_cpu(tmp);
>> >> > +               res = 0;
>> >> > +       }
>> >> >
>> >> > -       return le32_to_cpu(data);
>> >> > +       return res;
>> >> >  }
>> >> 
>> >> Dear Pavel,
>> >> 
>> >> OK, found the issue with decoded stack trace after reviewing this
>> >> usb_read32 function. Your line:
>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> >> 
>> >> should read:
>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
>> > 
>> > Dear Philip,
>> > 
>> > No, it should read:
>> > 
>> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
>> > 
>> > I suspect that Pavel didn't notice he was reusing a line of the old code
>> > wth no due changes.
>> > 
>> >> With this change, the driver runs fine with no crashes/oopses. I will
>> >> explain the issue but you can probably see already, so I hope I'm not
>> >> coming across as patronising, just trying to be helpful :-)
>> >> 
>> >> Essentially, you are taking the address of the data function parameter
>> >> on this line with &data, a pointer to u32, which is giving you a
>> >> pointer to a pointer to u32 (u32 **) for this function parameter
>> >> variable. When passed to usbctrl_vendorreq, it is being passed to
>> >> memcpy inside this function as a void *, meaning that memcpy
>> >> subsequently overwrites the value of the memory address inside data to
>> >> point to a different location, which is problem when it is later
>> >> deferenced at:
>> >> *data = le32_to_cpu(tmp);
>> >> causing the OOPS
>> >> 
>> >> Also, as written, you can probably see that tmp is uninitialised. This
>> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
>> >> with that small change, usbctrl_vendorreq reads into tmp, which is
>> >> then passed to le32_to_cpu whose return value is stored via the
>> >> deferenced data ptr (which now has its original address within and not
>> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
>> >> series if you want to resend this patch. Many thanks.
>> > 
>> > I think that another typo is having 'tmp', because that variable is unnecessary
>> > and "*data = le32_to_cpu(tmp);" is wrong too.
>> > 
>> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
>> > I had read yesterday) is the only correct function of the three usb_read*().
>> > 
>> 
>> Hi, guys!
>> 
>> 
>> Sorry for breaking your system, Phillip. This code was part of "last 
>> minute" changes and yes, it's broken :)
>> 
>> I get what Phillip said, because I _should_ read into tmp variable 
>> instead of directly to data, but I don't get Fabio's idea, sorry.
> 
> Hi Pavel,
> 
> I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
> endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
> with le32_to_cpu().
> 
> I simply thought that data could be passed to usbctrl_vendorreq as it-is.
> 
>> Data from chip comes in little-endian, so we _should_ convert it to 
>> cpu's endian. Temp variable is needed to make smatch and all other 
>> static anylis tools happy about this code.
> 
> Now that you explained that "Data from chip comes in little-endian", obviously
> I must agree with you that the code needs tmp and that tmp must be
> swapped by le32_to_cpu(), ahead of assigning it to *data.
> 
> Just a curiosity... Since I was not able to see that *data is returned in little endian,
> can you please point me where in the code you found out that it is? There must
> be some place in the code that I'm unable to find and see that *data is LE.
> 
> Thanks in advance,
> 
> Fabio

Hi, Fabio!

previous usb_read16() realization, which is 100% right:


static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
{
	u8 requesttype;
	u16 wvalue;
	u16 len;
	__le32 data;

	requesttype = 0x01;/* read_in */
	wvalue = (u16)(addr & 0x0000ffff);
	len = 2;
	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);

	return (u16)(le32_to_cpu(data) & 0xffff);
}


Bases on this code, I think, it's oblivious, that data comes in 
little-endian. That's why I leaved temp variable for casting le32 to 
cpu's endianess.

I could just read into u{16,32} * and then make smth like

*data = le32_to_cpu(*data)

but static analysis tools will complain about wrong data type passed to 
  le32_to_cpu()

+ Phillip tested fixed v2 version and it worked well for him. I guess, 
Phillip was able to spot weird driver behavior, if this cast is wrong.




With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  8:47                           ` Pavel Skripkin
@ 2021-08-24  8:53                             ` Pavel Skripkin
  2021-08-24  9:46                               ` Fabio M. De Francesco
  2021-08-24 22:10                               ` Phillip Potter
  2021-08-24 22:07                             ` Phillip Potter
  1 sibling, 2 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-24  8:53 UTC (permalink / raw)
  To: Fabio M. De Francesco, Phillip Potter
  Cc: Larry Finger, Greg KH, Michael Straube,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On 8/24/21 11:47 AM, Pavel Skripkin wrote:
> On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
>> On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
>>> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
>>> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
>>> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
>>> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>>> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>>> >> >  {
>>> >> >         u8 requesttype;
>>> >> >         u16 wvalue;
>>> >> >         u16 len;
>>> >> > -       __le32 data;
>>> >> > +       int res;
>>> >> > +       __le32 tmp;
>>> >> > +
>>> >> > +       if (WARN_ON(unlikely(!data)))
>>> >> > +               return -EINVAL;
>>> >> >
>>> >> >         requesttype = 0x01;/* read_in */
>>> >> >
>>> >> >         wvalue = (u16)(addr & 0x0000ffff);
>>> >> >         len = 4;
>>> >> >
>>> >> > -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>>> >> > +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>>> >> > +       if (res < 0) {
>>> >> > +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
>>> >> > +       } else {
>>> >> > +               /* Noone cares about positive return value */
>>> >> > +               *data = le32_to_cpu(tmp);
>>> >> > +               res = 0;
>>> >> > +       }
>>> >> >
>>> >> > -       return le32_to_cpu(data);
>>> >> > +       return res;
>>> >> >  }
>>> >> 
>>> >> Dear Pavel,
>>> >> 
>>> >> OK, found the issue with decoded stack trace after reviewing this
>>> >> usb_read32 function. Your line:
>>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>>> >> 
>>> >> should read:
>>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
>>> > 
>>> > Dear Philip,
>>> > 
>>> > No, it should read:
>>> > 
>>> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
>>> > 
>>> > I suspect that Pavel didn't notice he was reusing a line of the old code
>>> > wth no due changes.
>>> > 
>>> >> With this change, the driver runs fine with no crashes/oopses. I will
>>> >> explain the issue but you can probably see already, so I hope I'm not
>>> >> coming across as patronising, just trying to be helpful :-)
>>> >> 
>>> >> Essentially, you are taking the address of the data function parameter
>>> >> on this line with &data, a pointer to u32, which is giving you a
>>> >> pointer to a pointer to u32 (u32 **) for this function parameter
>>> >> variable. When passed to usbctrl_vendorreq, it is being passed to
>>> >> memcpy inside this function as a void *, meaning that memcpy
>>> >> subsequently overwrites the value of the memory address inside data to
>>> >> point to a different location, which is problem when it is later
>>> >> deferenced at:
>>> >> *data = le32_to_cpu(tmp);
>>> >> causing the OOPS
>>> >> 
>>> >> Also, as written, you can probably see that tmp is uninitialised. This
>>> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
>>> >> with that small change, usbctrl_vendorreq reads into tmp, which is
>>> >> then passed to le32_to_cpu whose return value is stored via the
>>> >> deferenced data ptr (which now has its original address within and not
>>> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
>>> >> series if you want to resend this patch. Many thanks.
>>> > 
>>> > I think that another typo is having 'tmp', because that variable is unnecessary
>>> > and "*data = le32_to_cpu(tmp);" is wrong too.
>>> > 
>>> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
>>> > I had read yesterday) is the only correct function of the three usb_read*().
>>> > 
>>> 
>>> Hi, guys!
>>> 
>>> 
>>> Sorry for breaking your system, Phillip. This code was part of "last 
>>> minute" changes and yes, it's broken :)
>>> 
>>> I get what Phillip said, because I _should_ read into tmp variable 
>>> instead of directly to data, but I don't get Fabio's idea, sorry.
>> 
>> Hi Pavel,
>> 
>> I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
>> endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
>> with le32_to_cpu().
>> 
>> I simply thought that data could be passed to usbctrl_vendorreq as it-is.
>> 
>>> Data from chip comes in little-endian, so we _should_ convert it to 
>>> cpu's endian. Temp variable is needed to make smatch and all other 
>>> static anylis tools happy about this code.
>> 
>> Now that you explained that "Data from chip comes in little-endian", obviously
>> I must agree with you that the code needs tmp and that tmp must be
>> swapped by le32_to_cpu(), ahead of assigning it to *data.
>> 
>> Just a curiosity... Since I was not able to see that *data is returned in little endian,
>> can you please point me where in the code you found out that it is? There must
>> be some place in the code that I'm unable to find and see that *data is LE.
>> 
>> Thanks in advance,
>> 
>> Fabio
> 
> Hi, Fabio!
> 
> previous usb_read16() realization, which is 100% right:
> 
> 
> static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> {
> 	u8 requesttype;
> 	u16 wvalue;
> 	u16 len;
> 	__le32 data;
> 
> 	requesttype = 0x01;/* read_in */
> 	wvalue = (u16)(addr & 0x0000ffff);
> 	len = 2;
> 	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> 
> 	return (u16)(le32_to_cpu(data) & 0xffff);
> }
> 
> 
> Bases on this code, I think, it's oblivious, that data comes in
> little-endian. That's why I leaved temp variable for casting le32 to
> cpu's endianess.
> 
> I could just read into u{16,32} * and then make smth like
> 
> *data = le32_to_cpu(*data)
> 
> but static analysis tools will complain about wrong data type passed to
>    le32_to_cpu()
> 
> + Phillip tested fixed v2 version and it worked well for him. I guess,
> Phillip was able to spot weird driver behavior, if this cast is wrong.
> 
		^^^^^&

I am wrong with this statement, I guess. Most likely, Phillip is testing 
on smth like x64 and this arch is le, so...




With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  8:53                             ` Pavel Skripkin
@ 2021-08-24  9:46                               ` Fabio M. De Francesco
  2021-08-24 22:10                               ` Phillip Potter
  1 sibling, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-24  9:46 UTC (permalink / raw)
  To: Phillip Potter, Pavel Skripkin
  Cc: Larry Finger, Greg KH, Michael Straube,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On Tuesday, August 24, 2021 10:53:35 AM CEST Pavel Skripkin wrote:
> On 8/24/21 11:47 AM, Pavel Skripkin wrote:
> > On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
> > 
> > Hi, Fabio!
> > 
> > previous usb_read16() realization, which is 100% right:
> > 
> > 
> > static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> > {
> > 	u8 requesttype;
> > 	u16 wvalue;
> > 	u16 len;
> > 	__le32 data;

Ah, it was in plain sight! How didn't I notice it? :(

> > 
> > 	requesttype = 0x01;/* read_in */
> > 	wvalue = (u16)(addr & 0x0000ffff);
> > 	len = 2;
> > 	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> > 
> > 	return (u16)(le32_to_cpu(data) & 0xffff);
> > }
> > 
> > 
> > Bases on this code, I think, it's oblivious, that data comes in
> > little-endian. That's why I leaved temp variable for casting le32 to
> > cpu's endianess.

Yes you did well (if we trust the old code :)), anyway I guess it
was correct because I've just seen that data is __le32 also in other Realtek
drivers.

> > 
> > I could just read into u{16,32} * and then make smth like
> > 
> > *data = le32_to_cpu(*data)
> > 
> > but static analysis tools will complain about wrong data type passed to
> >    le32_to_cpu()

Obviously the (not broken) tools should catch that and complain.

> > + Phillip tested fixed v2 version and it worked well for him. I guess,
> > Phillip was able to spot weird driver behavior, if this cast is wrong.
> > 
> 		^^^^^&
> 
> I am wrong with this statement, I guess. Most likely, Phillip is testing 
> on smth like x64 and this arch is le, so...
> 
> With regards,
> Pavel Skripkin
> 
Thanks,

Fabio



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  7:01                     ` Pavel Skripkin
@ 2021-08-24 15:07                       ` Fabio M. De Francesco
  0 siblings, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-24 15:07 UTC (permalink / raw)
  To: Dan Carpenter, Pavel Skripkin
  Cc: Larry.Finger, phil, gregkh, straube.linux, linux-staging, linux-kernel

On Tuesday, August 24, 2021 9:01:23 AM CEST Pavel Skripkin wrote:
> On 8/24/21 9:58 AM, Dan Carpenter wrote:
> > On Sun, Aug 22, 2021 at 05:36:01PM +0300, Pavel Skripkin wrote:
> >> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >>  {
> >>  	u8 requesttype;
> >>  	u16 wvalue;
> >>  	u16 len;
> >> -	__le32 data;
> >> +	int res;
> >> +	__le32 tmp;
> >> +
> >> +	if (WARN_ON(unlikely(!data)))
> >> +		return -EINVAL;
> >>  
> >>  	requesttype = 0x01;/* read_in */
> >>  
> >>  	wvalue = (u16)(addr & 0x0000ffff);
> >>  	len = 4;
> >>  
> >> -	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> +	res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> +	if (res < 0) {
> >> +		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> > 
> > Add a return here.  Try to keep the success path and the failure path
> > as separate as possible.  Try to keep the success path indented at one
> > tab so the code looks like this:
> > 
> > 	success();
> > 	success();
> > 	if (fail)
> > 		handle_failure();
> > 	success();
> > 	success();
> > 
> > Try to deal with exceptions as quickly as possible so that the reader
> > has less to remember.
> > 
> >> +	} else {
> >> +		/* Noone cares about positive return value */
> > 
> > Ugh...  That's unfortunate.  We should actually care.  The
> > usbctrl_vendorreq() has an information leak where it copies len (4)
> > bytes of data even if usb_control_msg() is not able to read len bytes.
> > 
> > The best fix would be to remove the information leak and make
> > usbctrl_vendorreq() return zero on success.  In other words something
> > like:
> > 
> > 	status = usb_control_msg();
> > 	if (status < 0)
> > 		return status;
> > 	if (status != len)
> > 		return -EIO;
> > 	status = 0;
> > 
> 
> I see, thank you for reviewing, will fix in v3! I fully forgot, that 
> usb_control_msg() can receive only part of the message :)

With the use of the new API I think that you don't have anymore
partial messages. usb_control_msg() returns the number of bytes 
transferred, while usb_control_msg_recv/send return only 0 if successful
otherwise a negative error number.

Regards,

Fabio

> With regards,
> Pavel Skripkin
> 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  8:47                           ` Pavel Skripkin
  2021-08-24  8:53                             ` Pavel Skripkin
@ 2021-08-24 22:07                             ` Phillip Potter
  1 sibling, 0 replies; 118+ messages in thread
From: Phillip Potter @ 2021-08-24 22:07 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Fabio M. De Francesco, Larry Finger, Greg KH, Michael Straube,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On Tue, 24 Aug 2021 at 09:47, Pavel Skripkin <paskripkin@gmail.com> wrote:
>
> On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
> > On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
> >> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
> >> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
> >> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
> >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >> >> >  {
> >> >> >         u8 requesttype;
> >> >> >         u16 wvalue;
> >> >> >         u16 len;
> >> >> > -       __le32 data;
> >> >> > +       int res;
> >> >> > +       __le32 tmp;
> >> >> > +
> >> >> > +       if (WARN_ON(unlikely(!data)))
> >> >> > +               return -EINVAL;
> >> >> >
> >> >> >         requesttype = 0x01;/* read_in */
> >> >> >
> >> >> >         wvalue = (u16)(addr & 0x0000ffff);
> >> >> >         len = 4;
> >> >> >
> >> >> > -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> >> > +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> >> > +       if (res < 0) {
> >> >> > +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> >> >> > +       } else {
> >> >> > +               /* Noone cares about positive return value */
> >> >> > +               *data = le32_to_cpu(tmp);
> >> >> > +               res = 0;
> >> >> > +       }
> >> >> >
> >> >> > -       return le32_to_cpu(data);
> >> >> > +       return res;
> >> >> >  }
> >> >>
> >> >> Dear Pavel,
> >> >>
> >> >> OK, found the issue with decoded stack trace after reviewing this
> >> >> usb_read32 function. Your line:
> >> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >> >>
> >> >> should read:
> >> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> >> >
> >> > Dear Philip,
> >> >
> >> > No, it should read:
> >> >
> >> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
> >> >
> >> > I suspect that Pavel didn't notice he was reusing a line of the old code
> >> > wth no due changes.
> >> >
> >> >> With this change, the driver runs fine with no crashes/oopses. I will
> >> >> explain the issue but you can probably see already, so I hope I'm not
> >> >> coming across as patronising, just trying to be helpful :-)
> >> >>
> >> >> Essentially, you are taking the address of the data function parameter
> >> >> on this line with &data, a pointer to u32, which is giving you a
> >> >> pointer to a pointer to u32 (u32 **) for this function parameter
> >> >> variable. When passed to usbctrl_vendorreq, it is being passed to
> >> >> memcpy inside this function as a void *, meaning that memcpy
> >> >> subsequently overwrites the value of the memory address inside data to
> >> >> point to a different location, which is problem when it is later
> >> >> deferenced at:
> >> >> *data = le32_to_cpu(tmp);
> >> >> causing the OOPS
> >> >>
> >> >> Also, as written, you can probably see that tmp is uninitialised. This
> >> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
> >> >> with that small change, usbctrl_vendorreq reads into tmp, which is
> >> >> then passed to le32_to_cpu whose return value is stored via the
> >> >> deferenced data ptr (which now has its original address within and not
> >> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
> >> >> series if you want to resend this patch. Many thanks.
> >> >
> >> > I think that another typo is having 'tmp', because that variable is unnecessary
> >> > and "*data = le32_to_cpu(tmp);" is wrong too.
> >> >
> >> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
> >> > I had read yesterday) is the only correct function of the three usb_read*().
> >> >
> >>
> >> Hi, guys!
> >>
> >>
> >> Sorry for breaking your system, Phillip. This code was part of "last
> >> minute" changes and yes, it's broken :)
> >>
> >> I get what Phillip said, because I _should_ read into tmp variable
> >> instead of directly to data, but I don't get Fabio's idea, sorry.
> >
> > Hi Pavel,
> >
> > I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
> > endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
> > with le32_to_cpu().
> >
> > I simply thought that data could be passed to usbctrl_vendorreq as it-is.
> >
> >> Data from chip comes in little-endian, so we _should_ convert it to
> >> cpu's endian. Temp variable is needed to make smatch and all other
> >> static anylis tools happy about this code.
> >
> > Now that you explained that "Data from chip comes in little-endian", obviously
> > I must agree with you that the code needs tmp and that tmp must be
> > swapped by le32_to_cpu(), ahead of assigning it to *data.
> >
> > Just a curiosity... Since I was not able to see that *data is returned in little endian,
> > can you please point me where in the code you found out that it is? There must
> > be some place in the code that I'm unable to find and see that *data is LE.
> >
> > Thanks in advance,
> >
> > Fabio
>
> Hi, Fabio!
>
> previous usb_read16() realization, which is 100% right:
>
>
> static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> {
>         u8 requesttype;
>         u16 wvalue;
>         u16 len;
>         __le32 data;
>
>         requesttype = 0x01;/* read_in */
>         wvalue = (u16)(addr & 0x0000ffff);
>         len = 2;
>         usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>
>         return (u16)(le32_to_cpu(data) & 0xffff);
> }
>
>
> Bases on this code, I think, it's oblivious, that data comes in
> little-endian. That's why I leaved temp variable for casting le32 to
> cpu's endianess.
>
> I could just read into u{16,32} * and then make smth like
>
> *data = le32_to_cpu(*data)
>
> but static analysis tools will complain about wrong data type passed to
>   le32_to_cpu()
>
> + Phillip tested fixed v2 version and it worked well for him. I guess,
> Phillip was able to spot weird driver behavior, if this cast is wrong.
>
>
>
>
> With regards,
> Pavel Skripkin

In my mind we can't necessarily assume we are running on a little
endian CPU, even if we probably are for practical purposes. That's why
my fix looked how it did, but I'm happy to be corrected :-) Also, I
can see Dan has looked at the code with suggestions as well. I know
you have published v3 - sorry, not had time to review/test it yet.

Regards,
Phil

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH RFC v2 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  8:53                             ` Pavel Skripkin
  2021-08-24  9:46                               ` Fabio M. De Francesco
@ 2021-08-24 22:10                               ` Phillip Potter
  1 sibling, 0 replies; 118+ messages in thread
From: Phillip Potter @ 2021-08-24 22:10 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Fabio M. De Francesco, Larry Finger, Greg KH, Michael Straube,
	open list:STAGING SUBSYSTEM, Linux Kernel Mailing List

On Tue, 24 Aug 2021 at 09:53, Pavel Skripkin <paskripkin@gmail.com> wrote:
>
> On 8/24/21 11:47 AM, Pavel Skripkin wrote:
> > On 8/24/21 11:38 AM, Fabio M. De Francesco wrote:
> >> On Tuesday, August 24, 2021 8:40:18 AM CEST Pavel Skripkin wrote:
> >>> On 8/24/21 3:10 AM, Fabio M. De Francesco wrote:
> >>> > On Tuesday, August 24, 2021 1:33:46 AM CEST Phillip Potter wrote:
> >>> >> On Sun, 22 Aug 2021 at 15:36, Pavel Skripkin <paskripkin@gmail.com> wrote:
> >>> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >>> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
> >>> >> >  {
> >>> >> >         u8 requesttype;
> >>> >> >         u16 wvalue;
> >>> >> >         u16 len;
> >>> >> > -       __le32 data;
> >>> >> > +       int res;
> >>> >> > +       __le32 tmp;
> >>> >> > +
> >>> >> > +       if (WARN_ON(unlikely(!data)))
> >>> >> > +               return -EINVAL;
> >>> >> >
> >>> >> >         requesttype = 0x01;/* read_in */
> >>> >> >
> >>> >> >         wvalue = (u16)(addr & 0x0000ffff);
> >>> >> >         len = 4;
> >>> >> >
> >>> >> > -       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >>> >> > +       res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >>> >> > +       if (res < 0) {
> >>> >> > +               dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> >>> >> > +       } else {
> >>> >> > +               /* Noone cares about positive return value */
> >>> >> > +               *data = le32_to_cpu(tmp);
> >>> >> > +               res = 0;
> >>> >> > +       }
> >>> >> >
> >>> >> > -       return le32_to_cpu(data);
> >>> >> > +       return res;
> >>> >> >  }
> >>> >>
> >>> >> Dear Pavel,
> >>> >>
> >>> >> OK, found the issue with decoded stack trace after reviewing this
> >>> >> usb_read32 function. Your line:
> >>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >>> >>
> >>> >> should read:
> >>> >> res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> >>> >
> >>> > Dear Philip,
> >>> >
> >>> > No, it should read:
> >>> >
> >>> > res = usbctrl_vendorreq(pintfhdl, wvalue, data, len, requesttype);
> >>> >
> >>> > I suspect that Pavel didn't notice he was reusing a line of the old code
> >>> > wth no due changes.
> >>> >
> >>> >> With this change, the driver runs fine with no crashes/oopses. I will
> >>> >> explain the issue but you can probably see already, so I hope I'm not
> >>> >> coming across as patronising, just trying to be helpful :-)
> >>> >>
> >>> >> Essentially, you are taking the address of the data function parameter
> >>> >> on this line with &data, a pointer to u32, which is giving you a
> >>> >> pointer to a pointer to u32 (u32 **) for this function parameter
> >>> >> variable. When passed to usbctrl_vendorreq, it is being passed to
> >>> >> memcpy inside this function as a void *, meaning that memcpy
> >>> >> subsequently overwrites the value of the memory address inside data to
> >>> >> point to a different location, which is problem when it is later
> >>> >> deferenced at:
> >>> >> *data = le32_to_cpu(tmp);
> >>> >> causing the OOPS
> >>> >>
> >>> >> Also, as written, you can probably see that tmp is uninitialised. This
> >>> >> looks like a typo, so guessing this wasn't your intention. Anyhow,
> >>> >> with that small change, usbctrl_vendorreq reads into tmp, which is
> >>> >> then passed to le32_to_cpu whose return value is stored via the
> >>> >> deferenced data ptr (which now has its original address within and not
> >>> >> inadvertently modified). Hope this helps, and I'd be happy to Ack the
> >>> >> series if you want to resend this patch. Many thanks.
> >>> >
> >>> > I think that another typo is having 'tmp', because that variable is unnecessary
> >>> > and "*data = le32_to_cpu(tmp);" is wrong too.
> >>> >
> >>> > Now I also see that also usb_read16() is wrong, while usb_read8() (the one that
> >>> > I had read yesterday) is the only correct function of the three usb_read*().
> >>> >
> >>>
> >>> Hi, guys!
> >>>
> >>>
> >>> Sorry for breaking your system, Phillip. This code was part of "last
> >>> minute" changes and yes, it's broken :)
> >>>
> >>> I get what Phillip said, because I _should_ read into tmp variable
> >>> instead of directly to data, but I don't get Fabio's idea, sorry.
> >>
> >> Hi Pavel,
> >>
> >> I (wrongly?) assumed from the prototype of usb_read32() that u32 *data is in native
> >> endianness. So, I didn't see the necessity of using _le32 tmp and then convert that tmp
> >> with le32_to_cpu().
> >>
> >> I simply thought that data could be passed to usbctrl_vendorreq as it-is.
> >>
> >>> Data from chip comes in little-endian, so we _should_ convert it to
> >>> cpu's endian. Temp variable is needed to make smatch and all other
> >>> static anylis tools happy about this code.
> >>
> >> Now that you explained that "Data from chip comes in little-endian", obviously
> >> I must agree with you that the code needs tmp and that tmp must be
> >> swapped by le32_to_cpu(), ahead of assigning it to *data.
> >>
> >> Just a curiosity... Since I was not able to see that *data is returned in little endian,
> >> can you please point me where in the code you found out that it is? There must
> >> be some place in the code that I'm unable to find and see that *data is LE.
> >>
> >> Thanks in advance,
> >>
> >> Fabio
> >
> > Hi, Fabio!
> >
> > previous usb_read16() realization, which is 100% right:
> >
> >
> > static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> > {
> >       u8 requesttype;
> >       u16 wvalue;
> >       u16 len;
> >       __le32 data;
> >
> >       requesttype = 0x01;/* read_in */
> >       wvalue = (u16)(addr & 0x0000ffff);
> >       len = 2;
> >       usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> >
> >       return (u16)(le32_to_cpu(data) & 0xffff);
> > }
> >
> >
> > Bases on this code, I think, it's oblivious, that data comes in
> > little-endian. That's why I leaved temp variable for casting le32 to
> > cpu's endianess.
> >
> > I could just read into u{16,32} * and then make smth like
> >
> > *data = le32_to_cpu(*data)
> >
> > but static analysis tools will complain about wrong data type passed to
> >    le32_to_cpu()
> >
> > + Phillip tested fixed v2 version and it worked well for him. I guess,
> > Phillip was able to spot weird driver behavior, if this cast is wrong.
> >
>                 ^^^^^&
>
> I am wrong with this statement, I guess. Most likely, Phillip is testing
> on smth like x64 and this arch is le, so...
>
>
>
>
> With regards,
> Pavel Skripkin

Dear Pavel,

You're correct in your assumption, my testing environment is an
little-endian x64 QEMU VM with USB passthrough for the wireless
adapter. I prefer to test this way so that driver crashes don't bring
down the whole machine :-)

Regards,
Phil

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-24  7:27                       ` [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16 Pavel Skripkin
@ 2021-08-25  4:35                         ` Fabio M. De Francesco
  2021-08-25  8:22                           ` Pavel Skripkin
  2021-08-26 10:50                         ` Greg KH
  1 sibling, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25  4:35 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel

On Tuesday, August 24, 2021 9:27:35 AM CEST Pavel Skripkin wrote:
> _rtw_read16 function can fail in case of usb transfer failure. But
> previous function prototype wasn't designed to return an error to
> caller. It can cause a lot uninit value bugs all across the driver code,
> since rtw_read16() returns local stack variable to caller.
> 
> Fix it by changing the prototype of this function. Now it returns an
> int: 0 on success, negative error value on failure and callers should pass
> the pointer to storage location for register value.
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> 
> [...]
>
> -static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
>  {
>  	u8 requesttype;
>  	u16 wvalue;
>  	u16 len;
> -	__le32 data;
> +	int res;
> +	__le32 tmp;
> +
> +	if (WARN_ON(unlikely(!data)))
> +		return -EINVAL;
>  
>  	requesttype = 0x01;/* read_in */
>  	wvalue = (u16)(addr & 0x0000ffff);
>  	len = 2;
> -	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> +	res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> +	if (res < 0) {
> +		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 16 bytes: %d\n", res);
> +		return res;
> +	} else if (res != len) {

Dear Pavel,

Please note that if and when my patch "Use usb_control_msg_recv / send () in 
usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true' 
and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.

> +		dev_err(dvobj_to_dev(pintfhdl->pintf_dev),
> +			"Failed to read 16 bytes, could read only %d bytes\n", res);
> +		return -EIO;
> +	}
>  
> -	return (u16)(le32_to_cpu(data) & 0xffff);
> +	*data = le32_to_cpu(tmp) & 0xffff;
> +
> +	return 0;
>  }

[...]

Regards,

Fabio




^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  7:27                       ` [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32 Pavel Skripkin
@ 2021-08-25  4:40                         ` Fabio M. De Francesco
  2021-08-26  8:51                         ` David Laight
  1 sibling, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25  4:40 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel, Pavel Skripkin

On Tuesday, August 24, 2021 9:27:42 AM CEST Pavel Skripkin wrote:
> _rtw_read32 function can fail in case of usb transfer failure. But
> previous function prototype wasn't designed to return an error to
> caller. It can cause a lot uninit value bugs all across the driver code,
> since rtw_read32() returns local stack variable to caller.
> 
> Fix it by changing the prototype of this function. Now it returns an
> int: 0 on success, negative error value on failure and callers should pass
> the pointer to storage location for register value.
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
>
> [...]
>  
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>  {
>  	u8 requesttype;
>  	u16 wvalue;
>  	u16 len;
> -	__le32 data;
> +	int res;
> +	__le32 tmp;
> +
> +	if (WARN_ON(unlikely(!data)))
> +		return -EINVAL;
>  
>  	requesttype = 0x01;/* read_in */
>  
>  	wvalue = (u16)(addr & 0x0000ffff);
>  	len = 4;
>  
> -	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
> +	res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
> +	if (res < 0) {
> +		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 32 bytes: %d\n", res);
> +		return res;
> +	} else if (res != len) {

Dear Pavel,

Please note that if and when my patch "Use usb_control_msg_recv / send () in 
usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true' 
and usb_read32() will always return -EIO even if usbctrl_vendorreq () succeeds.

> +		dev_err(dvobj_to_dev(pintfhdl->pintf_dev),
> +			"Failed to read 32 bytes, could read only %d bytes\n", res);
> +		return -EIO;
> +	}
> +
> +	*data = le32_to_cpu(tmp);
>  
> -	return le32_to_cpu(data);
> +	return 0;
>  }
>  
> [...]
>
Regards,

Fabio




^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25  4:35                         ` Fabio M. De Francesco
@ 2021-08-25  8:22                           ` Pavel Skripkin
  2021-08-25  9:48                             ` Fabio M. De Francesco
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-25  8:22 UTC (permalink / raw)
  To: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux
  Cc: linux-staging, linux-kernel

On 8/25/21 7:35 AM, Fabio M. De Francesco wrote:
> On Tuesday, August 24, 2021 9:27:35 AM CEST Pavel Skripkin wrote:
>> _rtw_read16 function can fail in case of usb transfer failure. But
>> previous function prototype wasn't designed to return an error to
>> caller. It can cause a lot uninit value bugs all across the driver code,
>> since rtw_read16() returns local stack variable to caller.
>> 
>> Fix it by changing the prototype of this function. Now it returns an
>> int: 0 on success, negative error value on failure and callers should pass
>> the pointer to storage location for register value.
>> 
>> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
>> 
>> [...]
>>
>> -static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
>> +static int usb_read16(struct intf_hdl *pintfhdl, u32 addr, u16 *data)
>>  {
>>  	u8 requesttype;
>>  	u16 wvalue;
>>  	u16 len;
>> -	__le32 data;
>> +	int res;
>> +	__le32 tmp;
>> +
>> +	if (WARN_ON(unlikely(!data)))
>> +		return -EINVAL;
>>  
>>  	requesttype = 0x01;/* read_in */
>>  	wvalue = (u16)(addr & 0x0000ffff);
>>  	len = 2;
>> -	usbctrl_vendorreq(pintfhdl, wvalue, &data, len, requesttype);
>> +	res = usbctrl_vendorreq(pintfhdl, wvalue, &tmp, len, requesttype);
>> +	if (res < 0) {
>> +		dev_err(dvobj_to_dev(pintfhdl->pintf_dev), "Failed to read 16 bytes: %d\n", res);
>> +		return res;
>> +	} else if (res != len) {
> 
> Dear Pavel,
> 
> Please note that if and when my patch "Use usb_control_msg_recv / send () in
> usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
> and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
> 

Yep, thank you, but it depends on which series will go in first :)

There is a chance, that you will need to clean up this part, if mine 
will be merged before yours



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25  8:22                           ` Pavel Skripkin
@ 2021-08-25  9:48                             ` Fabio M. De Francesco
  2021-08-25  9:55                               ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25  9:48 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel

On Wednesday, August 25, 2021 10:22:16 AM CEST Pavel Skripkin wrote:
> On 8/25/21 7:35 AM, Fabio M. De Francesco wrote:
> > Dear Pavel,
> > 
> > Please note that if and when my patch "Use usb_control_msg_recv / send () in
> > usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
> > and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
> > 
> 
> Yep, thank you, but it depends on which series will go in first :)
> 
> There is a chance, that you will need to clean up this part, if mine 
> will be merged before yours
> 

Ha-ha ... I know that beautiful rule: whoever breaks must fix! 
However there should be another rule which says that
the old (me) takes precedence over the young (you) :-)

Seriously, thank you so much for your help and the "Reviewed by" 
tag on my work.

Regards,

Fabio
  
> With regards,
> Pavel Skripkin
> 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25  9:48                             ` Fabio M. De Francesco
@ 2021-08-25  9:55                               ` Pavel Skripkin
  2021-08-25 10:06                                 ` Dan Carpenter
  2021-08-25 10:51                                 ` Fabio M. De Francesco
  0 siblings, 2 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-25  9:55 UTC (permalink / raw)
  To: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux
  Cc: linux-staging, linux-kernel

On 8/25/21 12:48 PM, Fabio M. De Francesco wrote:
> On Wednesday, August 25, 2021 10:22:16 AM CEST Pavel Skripkin wrote:
>> On 8/25/21 7:35 AM, Fabio M. De Francesco wrote:
>> > Dear Pavel,
>> > 
>> > Please note that if and when my patch "Use usb_control_msg_recv / send () in
>> > usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
>> > and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
>> > 
>> 
>> Yep, thank you, but it depends on which series will go in first :)
>> 
>> There is a chance, that you will need to clean up this part, if mine 
>> will be merged before yours
>> 
> 
> Ha-ha ... I know that beautiful rule: whoever breaks must fix!
> However there should be another rule which says that
> the old (me) takes precedence over the young (you) :-)
> 

The main problem, that no one knows who is the "old". Greg can take 
patches in any order he wants, because they are naturally independent :)


We only can say smth like "this one depends on this one" as reply to 
patch to inform Greg about the situation.

> Seriously, thank you so much for your help and the "Reviewed by"
> tag on my work.
> 

You too :) We are doing same job here for the good of community and 
kernel itself




With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25  9:55                               ` Pavel Skripkin
@ 2021-08-25 10:06                                 ` Dan Carpenter
  2021-08-25 10:13                                   ` Pavel Skripkin
  2021-08-25 10:51                                 ` Fabio M. De Francesco
  1 sibling, 1 reply; 118+ messages in thread
From: Dan Carpenter @ 2021-08-25 10:06 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux,
	linux-staging, linux-kernel

On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
> The main problem, that no one knows who is the "old". Greg can take patches
> in any order he wants

Patches are always taken in first come first serve.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
                                         ` (5 preceding siblings ...)
  2021-08-24  7:27                       ` [PATCH v3 6/6] staging: r8188eu: make ReadEFuse return an int Pavel Skripkin
@ 2021-08-25 10:13                       ` Fabio M. De Francesco
  2021-08-27  7:49                       ` Kari Argillander
  7 siblings, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25 10:13 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel, Pavel Skripkin

On Tuesday, August 24, 2021 9:25:45 AM CEST Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
> 
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
> 
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
> 
> To avoid this type of bugs, I've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
> 
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
> 
> 
> v2 -> v3:
>   1. Fixed OOPS in usb_read32(), caused by writing to u32 **
>   2. Fixed style in rtw_read32, rtw_read16 and rtw_read8 (Suggested by Dan)
>   3. Added error hanling when usb_control_msg() returns ret != len
>      NOTE: Dan suggested to add this to usbctrl_vendorreq(), but there is
>      pending series, which will get rid of usb_control_msg(), so (res != len)
>      check can be removed, when Fabio's series will go in
>   4. Removed RFC tag
> 
> v1 -> v2:
>   1. Make rtw_read*() return an error instead of initializing pointer to error
>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>      changes
>   3. Add new macro for printing register values (It helps to not copy-paste error
>      handling)
>   4. Removed {read,write}_macreg (Suggested by Phillip)
>   5. Rebased on top of staging-next
>   6. Cleaned checkpatch errors and warnings
> 
> 
> Phillip has tested fixed v2 version, AFAIU

I had already acked your series when it was an RFC but I guess
the tag gets lost now that you have submitted the "real" patches.

As said, I like the purpose and the overall design. Furthermore,
I have compiled and linked the whole series (make C=2 -j8 
drivers/staging/r8188eu W=1) and I can confirm it does not
introduce any errors and/or warnings.

Anyway I couldn't test the module, so (for all six patches)...

Acked-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>

Thanks,

Fabio

> Pavel Skripkin (6):
>   staging: r8188eu: remove {read,write}_macreg
>   staging: r8188eu: add helper macro for printing registers
>   staging: r8188eu: add error handling of rtw_read8
>   staging: r8188eu: add error handling of rtw_read16
>   staging: r8188eu: add error handling of rtw_read32
>   staging: r8188eu: make ReadEFuse return an int
> 
>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>  drivers/staging/r8188eu/core/rtw_efuse.c      | 125 +++--
>  drivers/staging/r8188eu/core/rtw_io.c         |  27 +-
>  drivers/staging/r8188eu/core/rtw_mp.c         |  70 ++-
>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  13 +-
>  drivers/staging/r8188eu/core/rtw_pwrctrl.c    |   5 +-
>  drivers/staging/r8188eu/core/rtw_sreset.c     |   9 +-
>  .../r8188eu/hal/Hal8188ERateAdaptive.c        |   8 +-
>  drivers/staging/r8188eu/hal/HalPhyRf_8188e.c  |  21 +-
>  drivers/staging/r8188eu/hal/HalPwrSeqCmd.c    |   9 +-
>  drivers/staging/r8188eu/hal/hal_com.c         |  23 +-
>  drivers/staging/r8188eu/hal/hal_intf.c        |   6 +-
>  drivers/staging/r8188eu/hal/odm_interface.c   |  12 +-
>  drivers/staging/r8188eu/hal/rtl8188e_cmd.c    |  33 +-
>  drivers/staging/r8188eu/hal/rtl8188e_dm.c     |   6 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 285 +++++++++---
>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  27 +-
>  drivers/staging/r8188eu/hal/rtl8188e_sreset.c |  22 +-
>  drivers/staging/r8188eu/hal/rtl8188eu_led.c   |  18 +-
>  drivers/staging/r8188eu/hal/usb_halinit.c     | 439 +++++++++++++++---
>  drivers/staging/r8188eu/hal/usb_ops_linux.c   |  62 ++-
>  drivers/staging/r8188eu/include/hal_intf.h    |   6 +-
>  .../staging/r8188eu/include/odm_interface.h   |   6 +-
>  .../staging/r8188eu/include/rtl8188e_hal.h    |   2 +-
>  drivers/staging/r8188eu/include/rtw_debug.h   |  13 +
>  drivers/staging/r8188eu/include/rtw_efuse.h   |   4 +-
>  drivers/staging/r8188eu/include/rtw_io.h      |  18 +-
>  drivers/staging/r8188eu/include/rtw_mp.h      |   2 -
>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 179 +++++--
>  drivers/staging/r8188eu/os_dep/usb_intf.c     |   3 +-
>  30 files changed, 1143 insertions(+), 389 deletions(-)
> 
> -- 
> 2.32.0
> 
> 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25 10:06                                 ` Dan Carpenter
@ 2021-08-25 10:13                                   ` Pavel Skripkin
  2021-08-25 10:38                                     ` Dan Carpenter
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-25 10:13 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux,
	linux-staging, linux-kernel

On 8/25/21 1:06 PM, Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
>> The main problem, that no one knows who is the "old". Greg can take patches
>> in any order he wants
> 
> Patches are always taken in first come first serve.
> 


Ok, but if pending patch needs new version, then it will be taken at the 
end?

Here is the situation we have:

	I have the patch series based on old function behavior, it was
	posted first

	Then Fabio posted refactoring of the function and it changes
	return values.


Both series are pending right now and made on top of staging-next 
branch. Who needs to rebase? I think, applying these series as-is can 
broke the driver, since error handling will be broken





With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25 10:13                                   ` Pavel Skripkin
@ 2021-08-25 10:38                                     ` Dan Carpenter
  2021-08-25 10:41                                       ` Pavel Skripkin
  2021-08-25 11:06                                       ` Fabio M. De Francesco
  0 siblings, 2 replies; 118+ messages in thread
From: Dan Carpenter @ 2021-08-25 10:38 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux,
	linux-staging, linux-kernel

On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
> On 8/25/21 1:06 PM, Dan Carpenter wrote:
> > On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
> > > The main problem, that no one knows who is the "old". Greg can take patches
> > > in any order he wants
> > 
> > Patches are always taken in first come first serve.
> > 
> 
> 
> Ok, but if pending patch needs new version, then it will be taken at the
> end?

Versions don't matter.  No one is tracking any of that.

A patch arrives.  It is either applied or rejected.  First come first
serve.

> 
> Here is the situation we have:
> 
> 	I have the patch series based on old function behavior, it was
> 	posted first
> 
> 	Then Fabio posted refactoring of the function and it changes
> 	return values.
> 
> 
> Both series are pending right now and made on top of staging-next branch.
> Who needs to rebase? I think, applying these series as-is can broke the
> driver, since error handling will be broken

That's a bug then.  The patch should be rejected.  You're not allowed to
break the code.

Also don't write patches which lead to merge order breaking the code
silently.  That makes it difficult for stable as well.  For example,
don't do this:

-void frob(int a, int b);
+void frob(int b, int a);

In that case, you would change the name of the function so that the
build would break when people mix old and new code.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25 10:38                                     ` Dan Carpenter
@ 2021-08-25 10:41                                       ` Pavel Skripkin
  2021-08-25 11:06                                       ` Fabio M. De Francesco
  1 sibling, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-25 10:41 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux,
	linux-staging, linux-kernel

On 8/25/21 1:38 PM, Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
>> On 8/25/21 1:06 PM, Dan Carpenter wrote:
>> > On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
>> > > The main problem, that no one knows who is the "old". Greg can take patches
>> > > in any order he wants
>> > 
>> > Patches are always taken in first come first serve.
>> > 
>> 
>> 
>> Ok, but if pending patch needs new version, then it will be taken at the
>> end?
> 
> Versions don't matter.  No one is tracking any of that.
> 
> A patch arrives.  It is either applied or rejected.  First come first
> serve.
> 

Ok, big thanks for explanation

>> 
>> Here is the situation we have:
>> 
>> 	I have the patch series based on old function behavior, it was
>> 	posted first
>> 
>> 	Then Fabio posted refactoring of the function and it changes
>> 	return values.
>> 
>> 
>> Both series are pending right now and made on top of staging-next branch.
>> Who needs to rebase? I think, applying these series as-is can broke the
>> driver, since error handling will be broken
> 
> That's a bug then.  The patch should be rejected.  You're not allowed to
> break the code.
> 
> Also don't write patches which lead to merge order breaking the code
> silently.  That makes it difficult for stable as well.  For example,
> don't do this:
> 
> -void frob(int a, int b);
> +void frob(int b, int a);
> 
> In that case, you would change the name of the function so that the
> build would break when people mix old and new code.
> 

Understandable, thank you :)





With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25  9:55                               ` Pavel Skripkin
  2021-08-25 10:06                                 ` Dan Carpenter
@ 2021-08-25 10:51                                 ` Fabio M. De Francesco
  1 sibling, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25 10:51 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel

On Wednesday, August 25, 2021 11:55:37 AM CEST Pavel Skripkin wrote:
> On 8/25/21 12:48 PM, Fabio M. De Francesco wrote:
> > On Wednesday, August 25, 2021 10:22:16 AM CEST Pavel Skripkin wrote:
> >> On 8/25/21 7:35 AM, Fabio M. De Francesco wrote:
> >> > Dear Pavel,
> >> > 
> >> > Please note that if and when my patch "Use usb_control_msg_recv / send () in
> >> > usbctrl_vendorreq ()" will be merged, "if (res! = len)" will always evaluate 'true'
> >> > and usb_read16 () will always return -EIO even if usbctrl_vendorreq () succeeds.
> >> > 
> >> 
> >> Yep, thank you, but it depends on which series will go in first :)
> >> 
> >> There is a chance, that you will need to clean up this part, if mine 
> >> will be merged before yours
> >> 
> > 
> > Ha-ha ... I know that beautiful rule: whoever breaks must fix!
> > However there should be another rule which says that
> > the old (me) takes precedence over the young (you) :-)
> > 
> 
> The main problem, that no one knows who is the "old". Greg can take 
> patches in any order he wants, because they are naturally independent :)
> 
> 
> We only can say smth like "this one depends on this one" as reply to 
> patch to inform Greg about the situation.
> 
> > Seriously, thank you so much for your help and the "Reviewed by"
> > tag on my work.
> > 
> 
> You too :) We are doing same job here for the good of community and 
> kernel itself
> 
Pavel, Dan,

Did you really take my "old" vs. "young" precedence rule seriously?

I was just kidding, ahead of thanking Pavel for his "Reviewed-by" tag
to my patch.

That statement deserved no comment. I thought it was
clear it was just a joke :)

Thanks,

Fabio
> 
> 
> With regards,
> Pavel Skripkin
> 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25 10:38                                     ` Dan Carpenter
  2021-08-25 10:41                                       ` Pavel Skripkin
@ 2021-08-25 11:06                                       ` Fabio M. De Francesco
  2021-08-25 11:11                                         ` Fabio M. De Francesco
  2021-08-25 11:31                                         ` Dan Carpenter
  1 sibling, 2 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25 11:06 UTC (permalink / raw)
  To: Pavel Skripkin, Dan Carpenter
  Cc: Larry.Finger, phil, gregkh, straube.linux, linux-staging, linux-kernel

On Wednesday, August 25, 2021 12:38:02 PM CEST Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
> > On 8/25/21 1:06 PM, Dan Carpenter wrote:
> > > On Wed, Aug 25, 2021 at 12:55:37PM +0300, Pavel Skripkin wrote:
> > > > The main problem, that no one knows who is the "old". Greg can take patches
> > > > in any order he wants
> > > 
> > > Patches are always taken in first come first serve.
> > > 
> > 
> > 
> > OK, but if pending patch needs new version, then it will be taken at the
> > end?
> 
> Versions don't matter.  No one is tracking any of that.
> 
> A patch arrives.  It is either applied or rejected.  First come first
> serve.
> 
> > 
> > Here is the situation we have:
> > 
> > 	I have the patch series based on old function behavior, it was
> > 	posted first
> > 
> > 	Then Fabio posted refactoring of the function and it changes
> > 	return values.
> > 
> > 
> > Both series are pending right now and made on top of staging-next branch.
> > Who needs to rebase? I think, applying these series as-is can broke the
> > driver, since error handling will be broken
> 
> That's a bug then.  The patch should be rejected.  You're not allowed to
> break the code.

Sorry Dan, I disagree. It's not a bug. No one intend to break the code. 
How could anyone know that someone else is working simultaneously on 
some code that is not compatible with the work of the other developer?

Pavel and I worked simultaneously on code based on the current Greg's tree.

We incidentally got to know that mine breaks his.

I suppose that Greg will take Pavel's work first, because it was submitted few 
hours before mine and then will ask me to take into account Pavel's patches, 
rebase, fix and resend mine.

Each series is self contained and does not introduce bugs to the current tree.
The bugs will arise when Greg will have applied one of the two series as usually 
in a FIFO order.

There's no practical means to know who is working to what just by reading all 
the messages of the lists. Who reads all the messages before deciding to work 
on something? This issue will be solved a way or the other, I really don't think it 
is a big problem, it's unavoidable when a lot of people work on the same 
driver or subsystem.

Regards,

Fabio  

> Also don't write patches which lead to merge order breaking the code
> silently.  That makes it difficult for stable as well.  For example,
> don't do this:
> 
> -void frob(int a, int b);
> +void frob(int b, int a);
> 
> In that case, you would change the name of the function so that the
> build would break when people mix old and new code.
> 
> regards,
> dan carpenter
> 
> 





^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25 11:06                                       ` Fabio M. De Francesco
@ 2021-08-25 11:11                                         ` Fabio M. De Francesco
  2021-08-25 11:31                                         ` Dan Carpenter
  1 sibling, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25 11:11 UTC (permalink / raw)
  To: Pavel Skripkin, Dan Carpenter
  Cc: Larry.Finger, phil, gregkh, straube.linux, linux-staging, linux-kernel

On Wednesday, August 25, 2021 1:06:40 PM CEST Fabio M. De Francesco wrote:
> On Wednesday, August 25, 2021 12:38:02 PM CEST Dan Carpenter wrote:

> > That's a bug then.  The patch should be rejected.  You're not allowed to
> > break the code.
> 
> Sorry Dan, I disagree. It's not a bug. No one intend to break the code. 
> How could anyone know that someone else is working simultaneously on 
> some code that is not compatible with the work of the other developer?
> 
> Pavel and I worked simultaneously on code based on the current Greg's tree.
> 
> We incidentally got to know that mine breaks his.
> 
> I suppose that Greg will take Pavel's work first, because it was submitted few 
> hours before mine and then will ask me to take into account Pavel's patches, 
> rebase, fix and resend mine.
> 
> Each series is self contained and does not introduce bugs to the current tree.
> The bugs will arise when Greg will have applied one of the two series as usually 
> in a FIFO order.
> 
> There's no practical means to know who is working to what just by reading all 
> the messages of the lists. Who reads all the messages before deciding to work 
> on something? This issue will be solved a way or the other, I really don't think it 
> is a big problem, it's unavoidable when a lot of people work on the same 
> driver or subsystem.
> 
> Regards,
> 
> Fabio  

For sake of completeness I want to say that when Pavel had only submitted RFC v2
my code didn't break his. It was only with his v3 that the bug went out. But v3 was 
submitted just few hours before mine.

Fabio



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25 11:06                                       ` Fabio M. De Francesco
  2021-08-25 11:11                                         ` Fabio M. De Francesco
@ 2021-08-25 11:31                                         ` Dan Carpenter
  2021-08-25 12:11                                           ` Fabio M. De Francesco
  1 sibling, 1 reply; 118+ messages in thread
From: Dan Carpenter @ 2021-08-25 11:31 UTC (permalink / raw)
  To: Fabio M. De Francesco, gregkh
  Cc: Pavel Skripkin, Larry.Finger, phil, straube.linux, linux-staging,
	linux-kernel

On Wed, Aug 25, 2021 at 01:06:40PM +0200, Fabio M. De Francesco wrote:
> On Wednesday, August 25, 2021 12:38:02 PM CEST Dan Carpenter wrote:
> > On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
> > > Both series are pending right now and made on top of staging-next branch.
> > > Who needs to rebase? I think, applying these series as-is can broke the
> > > driver, since error handling will be broken
> > 
> > That's a bug then.  The patch should be rejected.  You're not allowed to
> > break the code.
> 
> Sorry Dan, I disagree. It's not a bug. No one intend to break the code. 
> How could anyone know that someone else is working simultaneously on 
> some code that is not compatible with the work of the other developer?

Okay, I haven't been following the discussion closely.  If these patches
introduce a known bug, then I am going to be cross.

I'm really stressed out right now.  If you at all suspect that your
patches are going to introduce bugs then just go back and say "Sorry,
don't take this one, the way it conflicts with Pavels ends up
introducing a bug.  I'll resend after Pavel's patches are applied."

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-24  7:27                       ` [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8 Pavel Skripkin
@ 2021-08-25 12:05                         ` kernel test robot
  2021-08-25 12:17                           ` Pavel Skripkin
  2021-08-25 23:45                         ` Fabio M. De Francesco
                                           ` (3 subsequent siblings)
  4 siblings, 1 reply; 118+ messages in thread
From: kernel test robot @ 2021-08-25 12:05 UTC (permalink / raw)
  To: Pavel Skripkin, Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: clang-built-linux, kbuild-all, linux-staging, linux-kernel,
	Pavel Skripkin

[-- Attachment #1: Type: text/plain, Size: 22339 bytes --]

Hi Pavel,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on staging/staging-testing]

url:    https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
config: arm-buildonly-randconfig-r001-20210825 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
        git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/staging/r8188eu/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: expected expression
                   u8 tmp;
                   ^
   1 error generated.

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for QCOM_SCM
   Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
   Selected by
   - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU


vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c

  1450	
  1451	static void SetHwReg8188EU(struct adapter *Adapter, u8 variable, u8 *val)
  1452	{
  1453		struct hal_data_8188e	*haldata = GET_HAL_DATA(Adapter);
  1454		struct dm_priv	*pdmpriv = &haldata->dmpriv;
  1455		struct odm_dm_struct *podmpriv = &haldata->odmpriv;
  1456		int error;
  1457		u8 tmp;
  1458	
  1459		switch (variable) {
  1460		case HW_VAR_MEDIA_STATUS:
  1461			{
  1462				u8 val8;
  1463	
  1464				error = rtw_read8(Adapter, MSR, &val8);
  1465				if (error)
  1466					return;
  1467	
  1468				val8 &= 0x0c;
  1469				val8 |= *((u8 *)val);
  1470				rtw_write8(Adapter, MSR, val8);
  1471			}
  1472			break;
  1473		case HW_VAR_MEDIA_STATUS1:
  1474			{
  1475				u8 val8;
  1476	
  1477				error = rtw_read8(Adapter, MSR, &val8);
  1478				if (error)
  1479					return;
  1480	
  1481				val8 &= 0x03;
  1482				val8 |= *((u8 *)val) << 2;
  1483				rtw_write8(Adapter, MSR, val8);
  1484			}
  1485			break;
  1486		case HW_VAR_SET_OPMODE:
  1487			hw_var_set_opmode(Adapter, variable, val);
  1488			break;
  1489		case HW_VAR_MAC_ADDR:
  1490			hw_var_set_macaddr(Adapter, variable, val);
  1491			break;
  1492		case HW_VAR_BSSID:
  1493			hw_var_set_bssid(Adapter, variable, val);
  1494			break;
  1495		case HW_VAR_BASIC_RATE:
  1496			{
  1497				u16 BrateCfg = 0;
  1498				u8 RateIndex = 0;
  1499	
  1500				/*  2007.01.16, by Emily */
  1501				/*  Select RRSR (in Legacy-OFDM and CCK) */
  1502				/*  For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate. */
  1503				/*  We do not use other rates. */
  1504				HalSetBrateCfg(Adapter, val, &BrateCfg);
  1505				DBG_88E("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg);
  1506	
  1507				/* 2011.03.30 add by Luke Lee */
  1508				/* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
  1509				/* because CCK 2M has poor TXEVM */
  1510				/* CCK 5.5M & 11M ACK should be enabled for better performance */
  1511	
  1512				BrateCfg = (BrateCfg | 0xd) & 0x15d;
  1513				haldata->BasicRateSet = BrateCfg;
  1514	
  1515				BrateCfg |= 0x01; /*  default enable 1M ACK rate */
  1516				/*  Set RRSR rate table. */
  1517				rtw_write8(Adapter, REG_RRSR, BrateCfg & 0xff);
  1518				rtw_write8(Adapter, REG_RRSR + 1, (BrateCfg >> 8) & 0xff);
  1519	
  1520				error = rtw_read8(Adapter, REG_RRSR + 2, &tmp);
  1521				if (error)
  1522					return;
  1523	
  1524				rtw_write8(Adapter, REG_RRSR + 2, tmp & 0xf0);
  1525	
  1526				/*  Set RTS initial rate */
  1527				while (BrateCfg > 0x1) {
  1528					BrateCfg = (BrateCfg >> 1);
  1529					RateIndex++;
  1530				}
  1531				/*  Ziv - Check */
  1532				rtw_write8(Adapter, REG_INIRTS_RATE_SEL, RateIndex);
  1533			}
  1534			break;
  1535		case HW_VAR_TXPAUSE:
  1536			rtw_write8(Adapter, REG_TXPAUSE, *((u8 *)val));
  1537			break;
  1538		case HW_VAR_BCN_FUNC:
  1539			hw_var_set_bcn_func(Adapter, variable, val);
  1540			break;
  1541		case HW_VAR_CORRECT_TSF:
  1542			{
  1543				u64	tsf;
  1544				struct mlme_ext_priv	*pmlmeext = &Adapter->mlmeextpriv;
  1545				struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
  1546	
  1547				tsf = pmlmeext->TSFValue - do_div(pmlmeext->TSFValue,
  1548								  pmlmeinfo->bcn_interval * 1024) - 1024; /* us */
  1549	
  1550				if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
  1551					StopTxBeacon(Adapter);
  1552	
  1553				/* disable related TSF function */
  1554				error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
  1555				if (error)
  1556					return;
  1557	
  1558				rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(3)));
  1559	
  1560				rtw_write32(Adapter, REG_TSFTR, tsf);
  1561				rtw_write32(Adapter, REG_TSFTR + 4, tsf >> 32);
  1562	
  1563				/* enable related TSF function */
  1564				error =  rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
  1565				if (error)
  1566					return;
  1567	
  1568				rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(3));
  1569	
  1570				if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
  1571					ResumeTxBeacon(Adapter);
  1572			}
  1573			break;
  1574		case HW_VAR_CHECK_BSSID:
  1575			if (*((u8 *)val)) {
  1576				rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
  1577			} else {
  1578				u32 val32;
  1579	
  1580				val32 = rtw_read32(Adapter, REG_RCR);
  1581	
  1582				val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
  1583	
  1584				rtw_write32(Adapter, REG_RCR, val32);
  1585			}
  1586			break;
  1587		case HW_VAR_MLME_DISCONNECT:
  1588			/* Set RCR to not to receive data frame when NO LINK state */
  1589			/* reject all data frames */
  1590			rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
  1591	
  1592			/* reset TSF */
  1593			rtw_write8(Adapter, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
  1594	
  1595			/* disable update TSF */
  1596			error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
  1597			if (error)
  1598				return;
  1599	
  1600			rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
  1601			break;
  1602		case HW_VAR_MLME_SITESURVEY:
  1603			if (*((u8 *)val)) { /* under sitesurvey */
  1604				/* config RCR to receive different BSSID & not to receive data frame */
  1605				u32 v = rtw_read32(Adapter, REG_RCR);
  1606	
  1607				v &= ~(RCR_CBSSID_BCN);
  1608				rtw_write32(Adapter, REG_RCR, v);
  1609				/* reject all data frame */
  1610				rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
  1611	
  1612				/* disable update TSF */
  1613				error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
  1614				if (error)
  1615					return;
  1616				rtw_write8(Adapter, REG_BCN_CTRL, tmp | BIT(4));
  1617			} else { /* sitesurvey done */
  1618				struct mlme_ext_priv	*pmlmeext = &Adapter->mlmeextpriv;
  1619				struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
  1620	
  1621				error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
  1622				if (error)
  1623					return;
  1624	
  1625				if ((is_client_associated_to_ap(Adapter)) ||
  1626				    ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
  1627					/* enable to rx data frame */
  1628					rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
  1629	
  1630					/* enable update TSF */
  1631					rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
  1632				} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
  1633					rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
  1634					/* enable update TSF */
  1635					rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
  1636				}
  1637	
  1638				if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
  1639					rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
  1640				} else {
  1641					if (Adapter->in_cta_test) {
  1642						u32 v = rtw_read32(Adapter, REG_RCR);
  1643						v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
  1644						rtw_write32(Adapter, REG_RCR, v);
  1645					} else {
  1646						rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_BCN);
  1647					}
  1648				}
  1649			}
  1650			break;
  1651		case HW_VAR_MLME_JOIN:
  1652			{
  1653				u8 RetryLimit = 0x30;
  1654				u8 type = *((u8 *)val);
  1655				u8 tmp;
  1656				struct mlme_priv	*pmlmepriv = &Adapter->mlmepriv;
  1657	
  1658				if (type == 0) { /*  prepare to join */
  1659					/* enable to rx data frame.Accept all data frame */
  1660					rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);
  1661	
  1662					if (Adapter->in_cta_test) {
  1663						u32 v = rtw_read32(Adapter, REG_RCR);
  1664						v &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/*  RCR_ADF */
  1665						rtw_write32(Adapter, REG_RCR, v);
  1666					} else {
  1667						rtw_write32(Adapter, REG_RCR, rtw_read32(Adapter, REG_RCR) | RCR_CBSSID_DATA | RCR_CBSSID_BCN);
  1668					}
  1669	
  1670					if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
  1671						RetryLimit = (haldata->CustomerID == RT_CID_CCX) ? 7 : 48;
  1672					else /*  Ad-hoc Mode */
  1673						RetryLimit = 0x7;
  1674				} else if (type == 1) {
  1675					/* joinbss_event call back when join res < 0 */
  1676					rtw_write16(Adapter, REG_RXFLTMAP2, 0x00);
  1677				} else if (type == 2) {
  1678					/* sta add event call back */
  1679					/* enable update TSF */
  1680					error = rtw_read8(Adapter, REG_BCN_CTRL, &tmp);
  1681					if (error)
  1682						return;
  1683	
  1684					rtw_write8(Adapter, REG_BCN_CTRL, tmp & (~BIT(4)));
  1685	
  1686					if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
  1687						RetryLimit = 0x7;
  1688				}
  1689				rtw_write16(Adapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
  1690			}
  1691			break;
  1692		case HW_VAR_BEACON_INTERVAL:
  1693			rtw_write16(Adapter, REG_BCN_INTERVAL, *((u16 *)val));
  1694			break;
  1695		case HW_VAR_SLOT_TIME:
  1696			{
  1697				u8 u1bAIFS, aSifsTime;
  1698				struct mlme_ext_priv	*pmlmeext = &Adapter->mlmeextpriv;
  1699				struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
  1700	
  1701				rtw_write8(Adapter, REG_SLOT, val[0]);
  1702	
  1703				if (pmlmeinfo->WMM_enable == 0) {
  1704					if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
  1705						aSifsTime = 10;
  1706					else
  1707						aSifsTime = 16;
  1708	
  1709					u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
  1710	
  1711					/*  <Roger_EXP> Temporary removed, 2008.06.20. */
  1712					rtw_write8(Adapter, REG_EDCA_VO_PARAM, u1bAIFS);
  1713					rtw_write8(Adapter, REG_EDCA_VI_PARAM, u1bAIFS);
  1714					rtw_write8(Adapter, REG_EDCA_BE_PARAM, u1bAIFS);
  1715					rtw_write8(Adapter, REG_EDCA_BK_PARAM, u1bAIFS);
  1716				}
  1717			}
  1718			break;
  1719		case HW_VAR_RESP_SIFS:
  1720			/* RESP_SIFS for CCK */
  1721			rtw_write8(Adapter, REG_R2T_SIFS, val[0]); /*  SIFS_T2T_CCK (0x08) */
  1722			rtw_write8(Adapter, REG_R2T_SIFS + 1, val[1]); /* SIFS_R2T_CCK(0x08) */
  1723			/* RESP_SIFS for OFDM */
  1724			rtw_write8(Adapter, REG_T2T_SIFS, val[2]); /* SIFS_T2T_OFDM (0x0a) */
  1725			rtw_write8(Adapter, REG_T2T_SIFS + 1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
  1726			break;
  1727		case HW_VAR_ACK_PREAMBLE:
  1728			{
  1729				u8 regTmp;
  1730				u8 bShortPreamble = *((bool *)val);
  1731				/*  Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
  1732				regTmp = (haldata->nCur40MhzPrimeSC) << 5;
  1733				if (bShortPreamble)
  1734					regTmp |= 0x80;
  1735	
  1736				rtw_write8(Adapter, REG_RRSR + 2, regTmp);
  1737			}
  1738			break;
  1739		case HW_VAR_SEC_CFG:
  1740			rtw_write8(Adapter, REG_SECCFG, *((u8 *)val));
  1741			break;
  1742		case HW_VAR_DM_FLAG:
  1743			podmpriv->SupportAbility = *((u8 *)val);
  1744			break;
  1745		case HW_VAR_DM_FUNC_OP:
  1746			if (val[0])
  1747				podmpriv->BK_SupportAbility = podmpriv->SupportAbility;
  1748			else
  1749				podmpriv->SupportAbility = podmpriv->BK_SupportAbility;
  1750			break;
  1751		case HW_VAR_DM_FUNC_SET:
  1752			if (*((u32 *)val) == DYNAMIC_ALL_FUNC_ENABLE) {
  1753				pdmpriv->DMFlag = pdmpriv->InitDMFlag;
  1754				podmpriv->SupportAbility =	pdmpriv->InitODMFlag;
  1755			} else {
  1756				podmpriv->SupportAbility |= *((u32 *)val);
  1757			}
  1758			break;
  1759		case HW_VAR_DM_FUNC_CLR:
  1760			podmpriv->SupportAbility &= *((u32 *)val);
  1761			break;
  1762		case HW_VAR_CAM_EMPTY_ENTRY:
  1763			{
  1764				u8 ucIndex = *((u8 *)val);
  1765				u8 i;
  1766				u32 ulCommand = 0;
  1767				u32 ulContent = 0;
  1768				u32 ulEncAlgo = CAM_AES;
  1769	
  1770				for (i = 0; i < CAM_CONTENT_COUNT; i++) {
  1771					/*  filled id in CAM config 2 byte */
  1772					if (i == 0)
  1773						ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
  1774					else
  1775						ulContent = 0;
  1776					/*  polling bit, and No Write enable, and address */
  1777					ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
  1778					ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
  1779					/*  write content 0 is equall to mark invalid */
  1780					rtw_write32(Adapter, WCAMI, ulContent);  /* delay_ms(40); */
  1781					rtw_write32(Adapter, RWCAM, ulCommand);  /* delay_ms(40); */
  1782				}
  1783			}
  1784			break;
  1785		case HW_VAR_CAM_INVALID_ALL:
  1786			rtw_write32(Adapter, RWCAM, BIT(31) | BIT(30));
  1787			break;
  1788		case HW_VAR_CAM_WRITE:
  1789			{
  1790				u32 cmd;
  1791				u32 *cam_val = (u32 *)val;
  1792				rtw_write32(Adapter, WCAMI, cam_val[0]);
  1793	
  1794				cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
  1795				rtw_write32(Adapter, RWCAM, cmd);
  1796			}
  1797			break;
  1798		case HW_VAR_AC_PARAM_VO:
  1799			rtw_write32(Adapter, REG_EDCA_VO_PARAM, ((u32 *)(val))[0]);
  1800			break;
  1801		case HW_VAR_AC_PARAM_VI:
  1802			rtw_write32(Adapter, REG_EDCA_VI_PARAM, ((u32 *)(val))[0]);
  1803			break;
  1804		case HW_VAR_AC_PARAM_BE:
  1805			haldata->AcParam_BE = ((u32 *)(val))[0];
  1806			rtw_write32(Adapter, REG_EDCA_BE_PARAM, ((u32 *)(val))[0]);
  1807			break;
  1808		case HW_VAR_AC_PARAM_BK:
  1809			rtw_write32(Adapter, REG_EDCA_BK_PARAM, ((u32 *)(val))[0]);
  1810			break;
  1811		case HW_VAR_ACM_CTRL:
  1812			{
  1813				u8 acm_ctrl = *((u8 *)val);
  1814				u8 AcmCtrl;
  1815	
  1816				error = rtw_read8(Adapter, REG_ACMHWCTRL, &AcmCtrl);
  1817				if (error)
  1818					return;
  1819	
  1820				if (acm_ctrl > 1)
  1821					AcmCtrl = AcmCtrl | 0x1;
  1822	
  1823				if (acm_ctrl & BIT(3))
  1824					AcmCtrl |= AcmHw_VoqEn;
  1825				else
  1826					AcmCtrl &= (~AcmHw_VoqEn);
  1827	
  1828				if (acm_ctrl & BIT(2))
  1829					AcmCtrl |= AcmHw_ViqEn;
  1830				else
  1831					AcmCtrl &= (~AcmHw_ViqEn);
  1832	
  1833				if (acm_ctrl & BIT(1))
  1834					AcmCtrl |= AcmHw_BeqEn;
  1835				else
  1836					AcmCtrl &= (~AcmHw_BeqEn);
  1837	
  1838				DBG_88E("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
  1839				rtw_write8(Adapter, REG_ACMHWCTRL, AcmCtrl);
  1840			}
  1841			break;
  1842		case HW_VAR_AMPDU_MIN_SPACE:
  1843			{
  1844				u8 MinSpacingToSet;
  1845				u8 SecMinSpace;
  1846				u8 tmp;
  1847	
  1848				MinSpacingToSet = *((u8 *)val);
  1849				if (MinSpacingToSet <= 7) {
  1850					switch (Adapter->securitypriv.dot11PrivacyAlgrthm) {
  1851					case _NO_PRIVACY_:
  1852					case _AES_:
  1853						SecMinSpace = 0;
  1854						break;
  1855					case _WEP40_:
  1856					case _WEP104_:
  1857					case _TKIP_:
  1858					case _TKIP_WTMIC_:
  1859						SecMinSpace = 6;
  1860						break;
  1861					default:
  1862						SecMinSpace = 7;
  1863						break;
  1864					}
  1865					if (MinSpacingToSet < SecMinSpace)
  1866						MinSpacingToSet = SecMinSpace;
  1867	
  1868					error = rtw_read8(Adapter, REG_AMPDU_MIN_SPACE, &tmp);
  1869					if (error)
  1870						return;
  1871	
  1872					rtw_write8(Adapter, REG_AMPDU_MIN_SPACE, (tmp & 0xf8) |
  1873						  MinSpacingToSet);
  1874				}
  1875			}
  1876			break;
  1877		case HW_VAR_AMPDU_FACTOR:
  1878			{
  1879				u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9};
  1880				u8 FactorToSet;
  1881				u8 *pRegToSet;
  1882				u8 index = 0;
  1883	
  1884				pRegToSet = RegToSet_Normal; /*  0xb972a841; */
  1885				FactorToSet = *((u8 *)val);
  1886				if (FactorToSet <= 3) {
  1887					FactorToSet = (1 << (FactorToSet + 2));
  1888					if (FactorToSet > 0xf)
  1889						FactorToSet = 0xf;
  1890	
  1891					for (index = 0; index < 4; index++) {
  1892						if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
  1893							pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
  1894	
  1895						if ((pRegToSet[index] & 0x0f) > FactorToSet)
  1896							pRegToSet[index] = (pRegToSet[index] & 0xf0) | (FactorToSet);
  1897	
  1898						rtw_write8(Adapter, (REG_AGGLEN_LMT + index), pRegToSet[index]);
  1899					}
  1900				}
  1901			}
  1902			break;
  1903		case HW_VAR_RXDMA_AGG_PG_TH:
  1904			{
  1905				u8 threshold = *((u8 *)val);
  1906				if (threshold == 0)
  1907					threshold = haldata->UsbRxAggPageCount;
  1908				rtw_write8(Adapter, REG_RXDMA_AGG_PG_TH, threshold);
  1909			}
  1910			break;
  1911		case HW_VAR_SET_RPWM:
  1912			break;
  1913		case HW_VAR_H2C_FW_PWRMODE:
  1914			{
  1915				u8 psmode = (*(u8 *)val);
  1916	
  1917				/*  Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */
  1918				/*  saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */
  1919				if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(haldata->VersionID)))
  1920					ODM_RF_Saving(podmpriv, true);
  1921				rtl8188e_set_FwPwrMode_cmd(Adapter, psmode);
  1922			}
  1923			break;
  1924		case HW_VAR_H2C_FW_JOINBSSRPT:
  1925			{
  1926				u8 mstatus = (*(u8 *)val);
  1927				rtl8188e_set_FwJoinBssReport_cmd(Adapter, mstatus);
  1928			}
  1929			break;
  1930	#ifdef CONFIG_88EU_P2P
  1931		case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
  1932			{
  1933				u8 p2p_ps_state = (*(u8 *)val);
  1934				rtl8188e_set_p2p_ps_offload_cmd(Adapter, p2p_ps_state);
  1935			}
  1936			break;
  1937	#endif
  1938		case HW_VAR_INITIAL_GAIN:
  1939			{
  1940				struct rtw_dig *pDigTable = &podmpriv->DM_DigTable;
  1941				u32 rx_gain = ((u32 *)(val))[0];
  1942	
  1943				if (rx_gain == 0xff) {/* restore rx gain */
  1944					ODM_Write_DIG(podmpriv, pDigTable->BackupIGValue);
  1945				} else {
  1946					pDigTable->BackupIGValue = pDigTable->CurIGValue;
  1947					ODM_Write_DIG(podmpriv, rx_gain);
  1948				}
  1949			}
  1950			break;
  1951		case HW_VAR_TRIGGER_GPIO_0:
  1952			rtl8192cu_trigger_gpio_0(Adapter);
  1953			break;
  1954		case HW_VAR_RPT_TIMER_SETTING:
  1955			{
  1956				u16 min_rpt_time = (*(u16 *)val);
  1957				ODM_RA_Set_TxRPT_Time(podmpriv, min_rpt_time);
  1958			}
  1959			break;
  1960		case HW_VAR_ANTENNA_DIVERSITY_SELECT:
  1961			{
  1962				u8 Optimum_antenna = (*(u8 *)val);
  1963				u8 Ant;
  1964				/* switch antenna to Optimum_antenna */
  1965				if (haldata->CurAntenna !=  Optimum_antenna) {
  1966					Ant = (Optimum_antenna == 2) ? MAIN_ANT : AUX_ANT;
  1967					ODM_UpdateRxIdleAnt_88E(&haldata->odmpriv, Ant);
  1968	
  1969					haldata->CurAntenna = Optimum_antenna;
  1970				}
  1971			}
  1972			break;
  1973		case HW_VAR_EFUSE_BYTES: /*  To set EFUE total used bytes, added by Roger, 2008.12.22. */
  1974			haldata->EfuseUsedBytes = *((u16 *)val);
  1975			break;
  1976		case HW_VAR_FIFO_CLEARN_UP:
  1977			{
  1978				struct pwrctrl_priv *pwrpriv = &Adapter->pwrctrlpriv;
  1979				u8 trycnt = 100;
  1980	
  1981				/* pause tx */
  1982				rtw_write8(Adapter, REG_TXPAUSE, 0xff);
  1983	
  1984				/* keep sn */
  1985				Adapter->xmitpriv.nqos_ssn = rtw_read16(Adapter, REG_NQOS_SEQ);
  1986	
  1987				if (!pwrpriv->bkeepfwalive) {
  1988					/* RX DMA stop */
  1989					rtw_write32(Adapter, REG_RXPKT_NUM, (rtw_read32(Adapter, REG_RXPKT_NUM) | RW_RELEASE_EN));
  1990					do {
  1991						if (!(rtw_read32(Adapter, REG_RXPKT_NUM) & RXDMA_IDLE))
  1992							break;
  1993					} while (trycnt--);
  1994					if (trycnt == 0)
  1995						DBG_88E("Stop RX DMA failed......\n");
  1996	
  1997					/* RQPN Load 0 */
  1998					rtw_write16(Adapter, REG_RQPN_NPQ, 0x0);
  1999					rtw_write32(Adapter, REG_RQPN, 0x80000000);
  2000					mdelay(10);
  2001				}
  2002			}
  2003			break;
  2004		case HW_VAR_CHECK_TXBUF:
  2005			break;
  2006		case HW_VAR_APFM_ON_MAC:
  2007			haldata->bMacPwrCtrlOn = *val;
  2008			DBG_88E("%s: bMacPwrCtrlOn=%d\n", __func__, haldata->bMacPwrCtrlOn);
  2009			break;
  2010		case HW_VAR_TX_RPT_MAX_MACID:
  2011			{
  2012				u8 maxMacid = *val;
  2013				DBG_88E("### MacID(%d),Set Max Tx RPT MID(%d)\n", maxMacid, maxMacid + 1);
  2014				rtw_write8(Adapter, REG_TX_RPT_CTRL + 1, maxMacid + 1);
  2015			}
  2016			break;
  2017		case HW_VAR_H2C_MEDIA_STATUS_RPT:
  2018			rtl8188e_set_FwMediaStatus_cmd(Adapter, (*(__le16 *)val));
  2019			break;
  2020		case HW_VAR_BCN_VALID:
  2021			/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> 2022			u8 tmp;
  2023	
  2024			error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
  2025			if (error)
  2026				return;
  2027	
  2028			rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
  2029			break;
  2030		default:
  2031			break;
  2032		}
  2033	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 40744 bytes --]

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-25 11:31                                         ` Dan Carpenter
@ 2021-08-25 12:11                                           ` Fabio M. De Francesco
  0 siblings, 0 replies; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25 12:11 UTC (permalink / raw)
  To: gregkh, Dan Carpenter
  Cc: Pavel Skripkin, Larry.Finger, phil, straube.linux, linux-staging,
	linux-kernel

On Wednesday, August 25, 2021 1:31:22 PM CEST Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 01:06:40PM +0200, Fabio M. De Francesco wrote:
> > On Wednesday, August 25, 2021 12:38:02 PM CEST Dan Carpenter wrote:
> > > On Wed, Aug 25, 2021 at 01:13:54PM +0300, Pavel Skripkin wrote:
> > > > Both series are pending right now and made on top of staging-next branch.
> > > > Who needs to rebase? I think, applying these series as-is can broke the
> > > > driver, since error handling will be broken
> > > 
> > > That's a bug then.  The patch should be rejected.  You're not allowed to
> > > break the code.
> > 
> > Sorry Dan, I disagree. It's not a bug. No one intend to break the code. 
> > How could anyone know that someone else is working simultaneously on 
> > some code that is not compatible with the work of the other developer?
> 
> Okay, I haven't been following the discussion closely.  If these patches
> introduce a known bug, then I am going to be cross.
> 
> I'm really stressed out right now.  If you at all suspect that your
> patches are going to introduce bugs then just go back and say "Sorry,
> don't take this one, the way it conflicts with Pavel's ends up
> introducing a bug.  I'll resend after Pavel's patches are applied."
> 
> regards,
> dan carpenter
> 
Dear Dan,

Yours is a nice solution to this problem. 

I had thought that I should have waited for Greg to ask to take into account Pavel's 
series, change some lines of his code (because they are the only users of the new 
version of the helper function, that is my work - as suggested by Greg himself), 
rebase and resend, I really think that your idea is better.

I'll do as you suggest ASAP, within the end of the day (now I have to go).

Thanks very much.

Fabio



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-25 12:05                         ` kernel test robot
@ 2021-08-25 12:17                           ` Pavel Skripkin
  2021-08-25 12:51                             ` Dan Carpenter
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-25 12:17 UTC (permalink / raw)
  To: kernel test robot, Larry.Finger, phil, gregkh, straube.linux,
	fmdefrancesco
  Cc: clang-built-linux, kbuild-all, linux-staging, linux-kernel

On 8/25/21 3:05 PM, kernel test robot wrote:
> Hi Pavel,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on staging/staging-testing]
> 
> url:    https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
> config: arm-buildonly-randconfig-r001-20210825 (attached as .config)
> compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
> reproduce (this is a W=1 build):
>          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>          chmod +x ~/bin/make.cross
>          # install arm cross compiling tool for clang build
>          # apt-get install 11.1.1
>          # https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
>          git remote add linux-review https://github.com/0day-ci/linux
>          git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
>          git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
>          # save the attached .config to linux build tree
>          mkdir build_dir
>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/staging/r8188eu/
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>>> drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: expected expression
>                     u8 tmp;
>                     ^
>     1 error generated.
> 
> Kconfig warnings: (for reference only)
>     WARNING: unmet direct dependencies detected for QCOM_SCM
>     Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
>     Selected by
>     - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU
> 
> 

We need to fix Kconfig, ok, I will take a look at it later

> vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> 

>    2020		case HW_VAR_BCN_VALID:
>    2021			/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
>> 2022				u8 tmp;

Hm, I don't know anything about ARM compilers, so should I wrap this 
code block with {}?

My local gcc 11.1.1 (x86_64) does not produce any warnings/errors

>    2023	
>    2024			error = rtw_read8(Adapter, REG_TDECTRL + 2, &tmp);
>    2025			if (error)
>    2026				return;
>    2027	
>    2028			rtw_write8(Adapter, REG_TDECTRL + 2, tmp | BIT(0));
>    2029			break;
>    2030		default:
>    2031			break;
>    2032		}
>    2033	
> 



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-25 12:17                           ` Pavel Skripkin
@ 2021-08-25 12:51                             ` Dan Carpenter
  2021-08-25 13:02                               ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: Dan Carpenter @ 2021-08-25 12:51 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: kernel test robot, Larry.Finger, phil, gregkh, straube.linux,
	fmdefrancesco, clang-built-linux, kbuild-all, linux-staging,
	linux-kernel

On Wed, Aug 25, 2021 at 03:17:06PM +0300, Pavel Skripkin wrote:
> On 8/25/21 3:05 PM, kernel test robot wrote:
> > Hi Pavel,
> > 
> > Thank you for the patch! Yet something to improve:
> > 
> > [auto build test ERROR on staging/staging-testing]
> > 
> > url:    https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
> > config: arm-buildonly-randconfig-r001-20210825 (attached as .config)
> > compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
> > reproduce (this is a W=1 build):
> >          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> >          chmod +x ~/bin/make.cross
> >          # install arm cross compiling tool for clang build
> >          # apt-get install 11.1.1
> >          # https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
> >          git remote add linux-review https://github.com/0day-ci/linux
> >          git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
> >          git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
> >          # save the attached .config to linux build tree
> >          mkdir build_dir
> >          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/staging/r8188eu/
> > 
> > If you fix the issue, kindly add following tag as appropriate
> > Reported-by: kernel test robot <lkp@intel.com>
> > 
> > All errors (new ones prefixed by >>):
> > 
> > > > drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: expected expression
> >                     u8 tmp;
> >                     ^
> >     1 error generated.
> > 
> > Kconfig warnings: (for reference only)
> >     WARNING: unmet direct dependencies detected for QCOM_SCM
> >     Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
> >     Selected by
> >     - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU
> > 
> > 
> 
> We need to fix Kconfig, ok, I will take a look at it later
> 

This is not related to your patch.  Ignore it.


> > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> > 
> 
> >    2020		case HW_VAR_BCN_VALID:
> >    2021			/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> > > 2022				u8 tmp;
> 
> Hm, I don't know anything about ARM compilers, so should I wrap this code
> block with {}?

Yep.

> 
> My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
> 

You should figure out whats up with that because it shouldn't compile
with the gcc options that the kernel uses.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-25 12:51                             ` Dan Carpenter
@ 2021-08-25 13:02                               ` Pavel Skripkin
  2021-08-25 13:34                                 ` Dan Carpenter
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-25 13:02 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: kernel test robot, Larry.Finger, phil, gregkh, straube.linux,
	fmdefrancesco, clang-built-linux, kbuild-all, linux-staging,
	linux-kernel

On 8/25/21 3:51 PM, Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 03:17:06PM +0300, Pavel Skripkin wrote:
>> On 8/25/21 3:05 PM, kernel test robot wrote:
>> > Hi Pavel,
>> > 
>> > Thank you for the patch! Yet something to improve:
>> > 
>> > [auto build test ERROR on staging/staging-testing]
>> > 
>> > url:    https://github.com/0day-ci/linux/commits/Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
>> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 093991aaadf0fbb34184fa37a46e7a157da3f386
>> > config: arm-buildonly-randconfig-r001-20210825 (attached as .config)
>> > compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ea08c4cd1c0869ec5024a8bb3f5cdf06ab03ae83)
>> > reproduce (this is a W=1 build):
>> >          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>> >          chmod +x ~/bin/make.cross
>> >          # install arm cross compiling tool for clang build
>> >          # apt-get install 11.1.1
>> >          # https://github.com/0day-ci/linux/commit/d4e4bbed4e59df37967086f60fe92cb1b4504d37
>> >          git remote add linux-review https://github.com/0day-ci/linux
>> >          git fetch --no-tags linux-review Pavel-Skripkin/staging-r8188eu-remove-read-write-_macreg/20210824-162756
>> >          git checkout d4e4bbed4e59df37967086f60fe92cb1b4504d37
>> >          # save the attached .config to linux build tree
>> >          mkdir build_dir
>> >          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/staging/r8188eu/
>> > 
>> > If you fix the issue, kindly add following tag as appropriate
>> > Reported-by: kernel test robot <lkp@intel.com>
>> > 
>> > All errors (new ones prefixed by >>):
>> > 
>> > > > drivers/staging/r8188eu/hal/usb_halinit.c:2022:3: error: expected expression
>> >                     u8 tmp;
>> >                     ^
>> >     1 error generated.
>> > 
>> > Kconfig warnings: (for reference only)
>> >     WARNING: unmet direct dependencies detected for QCOM_SCM
>> >     Depends on (ARM || ARM64) && HAVE_ARM_SMCCC
>> >     Selected by
>> >     - ARM_QCOM_SPM_CPUIDLE && CPU_IDLE && (ARM || ARM64) && (ARCH_QCOM || COMPILE_TEST && !ARM64 && MMU
>> > 
>> > 
>> 
>> We need to fix Kconfig, ok, I will take a look at it later
>> 
> 
> This is not related to your patch.  Ignore it.
> 
> 
>> > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
>> > 
>> 
>> >    2020		case HW_VAR_BCN_VALID:
>> >    2021			/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
>> > > 2022				u8 tmp;
>> 
>> Hm, I don't know anything about ARM compilers, so should I wrap this code
>> block with {}?
> 
> Yep.
> 
>> 
>> My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
>> 
> 
> You should figure out whats up with that because it shouldn't compile
> with the gcc options that the kernel uses.
> 

AFAIK, at least 2 guys except me in this CC list compiled my series 
without errors/warnings. Maybe, staging tree is missing some Makefile 
updates?


I'll resend series this evening anyway, but this is strange....



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-25 13:02                               ` Pavel Skripkin
@ 2021-08-25 13:34                                 ` Dan Carpenter
  2021-08-25 13:44                                   ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: Dan Carpenter @ 2021-08-25 13:34 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: kernel test robot, Larry.Finger, phil, gregkh, straube.linux,
	fmdefrancesco, clang-built-linux, kbuild-all, linux-staging,
	linux-kernel

On Wed, Aug 25, 2021 at 04:02:26PM +0300, Pavel Skripkin wrote:
> > This is not related to your patch.  Ignore it.
> > 
> > 
> > > > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> > > >
> > > 
> > > >    2020		case HW_VAR_BCN_VALID:
> > > >    2021			/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> > > > > 2022				u8 tmp;
> > > 
> > > Hm, I don't know anything about ARM compilers, so should I wrap this code
> > > block with {}?
> > 
> > Yep.
> > 
> > > 
> > > My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
> > > 
> > 
> > You should figure out whats up with that because it shouldn't compile
> > with the gcc options that the kernel uses.
> > 
> 
> AFAIK, at least 2 guys except me in this CC list compiled my series without
> errors/warnings. Maybe, staging tree is missing some Makefile updates?
> 
> 
> I'll resend series this evening anyway, but this is strange....

Hm...  In my version of GCC the error is:

drivers/staging/r8188eu/hal/usb_halinit.c:1870:3: error: a label can only be part of a statement and a declaration is not a statement

That's a different error from what I was expecting.  It's caused by
having a declaration directly after a case statement.  The warning that
I was expecting was from -Wdeclaration-after-statement and it looks
like this:

warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]

You really should try investigate why this compiles for you because
something is going wrong.  It should not build without a warning.

regards,
dan carpenter



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-25 13:34                                 ` Dan Carpenter
@ 2021-08-25 13:44                                   ` Pavel Skripkin
  2021-08-25 17:11                                     ` Nick Desaulniers
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-25 13:44 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: kernel test robot, Larry.Finger, phil, gregkh, straube.linux,
	fmdefrancesco, clang-built-linux, kbuild-all, linux-staging,
	linux-kernel

On 8/25/21 4:34 PM, Dan Carpenter wrote:
> On Wed, Aug 25, 2021 at 04:02:26PM +0300, Pavel Skripkin wrote:
>> > This is not related to your patch.  Ignore it.
>> > 
>> > 
>> > > > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
>> > > >
>> > > 
>> > > >    2020		case HW_VAR_BCN_VALID:
>> > > >    2021			/* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
>> > > > > 2022				u8 tmp;
>> > > 
>> > > Hm, I don't know anything about ARM compilers, so should I wrap this code
>> > > block with {}?
>> > 
>> > Yep.
>> > 
>> > > 
>> > > My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
>> > > 
>> > 
>> > You should figure out whats up with that because it shouldn't compile
>> > with the gcc options that the kernel uses.
>> > 
>> 
>> AFAIK, at least 2 guys except me in this CC list compiled my series without
>> errors/warnings. Maybe, staging tree is missing some Makefile updates?
>> 
>> 
>> I'll resend series this evening anyway, but this is strange....
> 
> Hm...  In my version of GCC the error is:
> 
> drivers/staging/r8188eu/hal/usb_halinit.c:1870:3: error: a label can only be part of a statement and a declaration is not a statement
> 
> That's a different error from what I was expecting.  It's caused by
> having a declaration directly after a case statement.  The warning that
> I was expecting was from -Wdeclaration-after-statement and it looks
> like this:
> 
> warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
> 
> You really should try investigate why this compiles for you because
> something is going wrong.  It should not build without a warning.
> 

Looks like it's bug in gcc 11.1.1. I've rebuilt this module with gcc 10 
(gcc-10 (SUSE Linux) 10.3.1 20210707 [revision 
048117e16c77f82598fca9af585500572d46ad73]) and build fails with error 
described above


My default gcc is

gcc (SUSE Linux) 11.1.1 20210721 [revision 
076930b9690ac3564638636f6b13bbb6bc608aea]


Any idea? :)


With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-25 13:44                                   ` Pavel Skripkin
@ 2021-08-25 17:11                                     ` Nick Desaulniers
  2021-08-26 11:08                                       ` Dan Carpenter
  0 siblings, 1 reply; 118+ messages in thread
From: Nick Desaulniers @ 2021-08-25 17:11 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Dan Carpenter, kernel test robot, Larry.Finger, phil, gregkh,
	straube.linux, fmdefrancesco, clang-built-linux, kbuild-all,
	linux-staging, linux-kernel

On Wed, Aug 25, 2021 at 6:44 AM Pavel Skripkin <paskripkin@gmail.com> wrote:
>
> On 8/25/21 4:34 PM, Dan Carpenter wrote:
> > On Wed, Aug 25, 2021 at 04:02:26PM +0300, Pavel Skripkin wrote:
> >> > This is not related to your patch.  Ignore it.
> >> >
> >> >
> >> > > > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> >> > > >
> >> > >
> >> > > >    2020                case HW_VAR_BCN_VALID:
> >> > > >    2021                        /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> >> > > > > 2022                         u8 tmp;
> >> > >
> >> > > Hm, I don't know anything about ARM compilers, so should I wrap this code
> >> > > block with {}?
> >> >
> >> > Yep.
> >> >
> >> > >
> >> > > My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
> >> > >
> >> >
> >> > You should figure out whats up with that because it shouldn't compile
> >> > with the gcc options that the kernel uses.
> >> >
> >>
> >> AFAIK, at least 2 guys except me in this CC list compiled my series without
> >> errors/warnings. Maybe, staging tree is missing some Makefile updates?
> >>
> >>
> >> I'll resend series this evening anyway, but this is strange....
> >
> > Hm...  In my version of GCC the error is:
> >
> > drivers/staging/r8188eu/hal/usb_halinit.c:1870:3: error: a label can only be part of a statement and a declaration is not a statement
> >
> > That's a different error from what I was expecting.  It's caused by
> > having a declaration directly after a case statement.  The warning that
> > I was expecting was from -Wdeclaration-after-statement and it looks
> > like this:
> >
> > warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
> >
> > You really should try investigate why this compiles for you because
> > something is going wrong.  It should not build without a warning.
> >
>
> Looks like it's bug in gcc 11.1.1. I've rebuilt this module with gcc 10
> (gcc-10 (SUSE Linux) 10.3.1 20210707 [revision
> 048117e16c77f82598fca9af585500572d46ad73]) and build fails with error
> described above
>
>
> My default gcc is
>
> gcc (SUSE Linux) 11.1.1 20210721 [revision
> 076930b9690ac3564638636f6b13bbb6bc608aea]
>
>
> Any idea? :)

The original report said the build was with clang-14, which is near
top of tree and unreleased. It's possible that that build had a bug
that hopefully was reverted.

-- 
Thanks,
~Nick Desaulniers

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-24  7:27                       ` [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8 Pavel Skripkin
  2021-08-25 12:05                         ` kernel test robot
@ 2021-08-25 23:45                         ` Fabio M. De Francesco
  2021-08-26  5:13                           ` Pavel Skripkin
  2021-08-26  8:21                         ` David Laight
                                           ` (2 subsequent siblings)
  4 siblings, 1 reply; 118+ messages in thread
From: Fabio M. De Francesco @ 2021-08-25 23:45 UTC (permalink / raw)
  To: Larry.Finger, phil, gregkh, straube.linux, Pavel Skripkin
  Cc: linux-staging, linux-kernel, Pavel Skripkin

On Tuesday, August 24, 2021 9:27:27 AM CEST Pavel Skripkin wrote:
> _rtw_read8 function can fail in case of usb transfer failure. But
> previous function prototype wasn't designed to return an error to
> caller. It can cause a lot uninit value bugs all across the driver code,
> since rtw_read8() returns local stack variable to caller.
> 
> Fix it by changing the prototype of this function. Now it returns an
> int: 0 on success, negative error value on failure and callers should pass
> the pointer to storage location for register value.
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>

Dear Pavel,

I have to inform you that building patch v3 3/6 with gcc (version 11.1.1 20210721 
[revision 076930b9690ac3564638636f6b13bbb6bc608aea] (SUSE Linux)), gives
the following warning:

drivers/staging/r8188eu/os_dep/ioctl_linux.c:2258:13: warning: variable ‘error’ set but not used [-Wunused-but-set-variable]
 2258 |         int error;
      |             ^~~~~

I'm sorry, but I guess that for some reason previously I had only built v2 of your patch 
which had no warnings at all. 

Unfortunately, introducing warnings is not allowed.

While we are at this, I can also confirm that GCC 11.1.1 _does_ _not_ emit the warning 
that has been reported by the kernel test robot. 

Regards,

Fabio

 



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-25 23:45                         ` Fabio M. De Francesco
@ 2021-08-26  5:13                           ` Pavel Skripkin
  0 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-26  5:13 UTC (permalink / raw)
  To: Fabio M. De Francesco, Larry.Finger, phil, gregkh, straube.linux
  Cc: linux-staging, linux-kernel

On 8/26/21 2:45 AM, Fabio M. De Francesco wrote:
> On Tuesday, August 24, 2021 9:27:27 AM CEST Pavel Skripkin wrote:
>> _rtw_read8 function can fail in case of usb transfer failure. But
>> previous function prototype wasn't designed to return an error to
>> caller. It can cause a lot uninit value bugs all across the driver code,
>> since rtw_read8() returns local stack variable to caller.
>> 
>> Fix it by changing the prototype of this function. Now it returns an
>> int: 0 on success, negative error value on failure and callers should pass
>> the pointer to storage location for register value.
>> 
>> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> 
> Dear Pavel,
> 
> I have to inform you that building patch v3 3/6 with gcc (version 11.1.1 20210721
> [revision 076930b9690ac3564638636f6b13bbb6bc608aea] (SUSE Linux)), gives
> the following warning:
> 
> drivers/staging/r8188eu/os_dep/ioctl_linux.c:2258:13: warning: variable ‘error’ set but not used [-Wunused-but-set-variable]
>   2258 |         int error;
>        |             ^~~~~
> 
> I'm sorry, but I guess that for some reason previously I had only built v2 of your patch
> which had no warnings at all.
> 
> Unfortunately, introducing warnings is not allowed.
> 
> While we are at this, I can also confirm that GCC 11.1.1 _does_ _not_ emit the warning
> that has been reported by the kernel test robot.
> 

Yep, I see, thank you. v4 is on the way... I had a plan to send v4 
yesterday, but I've finally received r8188eu device.

I tried to connect it and test and.... driver didn't work :) So, I will 
try to figure out the problem with driver (or device) and will send v4.

Again, thank you for report :) My default gcc is too polite...




With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* RE: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-24  7:27                       ` [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8 Pavel Skripkin
  2021-08-25 12:05                         ` kernel test robot
  2021-08-25 23:45                         ` Fabio M. De Francesco
@ 2021-08-26  8:21                         ` David Laight
  2021-08-26  8:27                           ` Pavel Skripkin
  2021-08-27  9:07                         ` Dan Carpenter
  2021-08-30 11:21                         ` kernel test robot
  4 siblings, 1 reply; 118+ messages in thread
From: David Laight @ 2021-08-26  8:21 UTC (permalink / raw)
  To: 'Pavel Skripkin',
	Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel

From: Pavel Skripkin
> Sent: 24 August 2021 08:27
> 
> _rtw_read8 function can fail in case of usb transfer failure. But
> previous function prototype wasn't designed to return an error to
> caller. It can cause a lot uninit value bugs all across the driver code,
> since rtw_read8() returns local stack variable to caller.
> 
> Fix it by changing the prototype of this function. Now it returns an
> int: 0 on success, negative error value on failure and callers should pass
> the pointer to storage location for register value.

...
> +		len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n",
> +				proc_get_read_addr, (u8) tmp);

That is broken.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-26  8:21                         ` David Laight
@ 2021-08-26  8:27                           ` Pavel Skripkin
  2021-08-26 10:19                             ` David Laight
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-26  8:27 UTC (permalink / raw)
  To: David Laight
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On Thu, 26 Aug 2021 08:21:34 +0000
David Laight <David.Laight@ACULAB.COM> wrote:

> From: Pavel Skripkin
> > Sent: 24 August 2021 08:27
> > 
> > _rtw_read8 function can fail in case of usb transfer failure. But
> > previous function prototype wasn't designed to return an error to
> > caller. It can cause a lot uninit value bugs all across the driver
> > code, since rtw_read8() returns local stack variable to caller.
> > 
> > Fix it by changing the prototype of this function. Now it returns an
> > int: 0 on success, negative error value on failure and callers
> > should pass the pointer to storage location for register value.
> 
> ...
> > +		len += snprintf(page + len, count - len,
> > "rtw_read8(0x%x)=0x%x\n",
> > +				proc_get_read_addr, (u8) tmp);
> 
> That is broken.
> 

Don't get it, sorry. Previous code did exactly the same thing, but
didn't check if read() was successful.





With regards,
Pavel Skripkin



^ permalink raw reply	[flat|nested] 118+ messages in thread

* RE: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-24  7:27                       ` [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32 Pavel Skripkin
  2021-08-25  4:40                         ` Fabio M. De Francesco
@ 2021-08-26  8:51                         ` David Laight
  2021-08-26  9:22                           ` Pavel Skripkin
  1 sibling, 1 reply; 118+ messages in thread
From: David Laight @ 2021-08-26  8:51 UTC (permalink / raw)
  To: 'Pavel Skripkin',
	Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco
  Cc: linux-staging, linux-kernel

From: Pavel Skripkin <paskripkin@gmail.com>
> Sent: 24 August 2021 08:28
> 
> _rtw_read32 function can fail in case of usb transfer failure. But
> previous function prototype wasn't designed to return an error to
> caller. It can cause a lot uninit value bugs all across the driver code,
> since rtw_read32() returns local stack variable to caller.
> 
> Fix it by changing the prototype of this function. Now it returns an
> int: 0 on success, negative error value on failure and callers should pass
> the pointer to storage location for register value.

Pretty horrid API interface.
Functions like readl() - which can fail just return ~0u and let
the caller worry about whether that causes serious grief.

You could make all the read functions return __u64 and return ~0ull
on error.
Testing for (value & 1ull << 63) will be reasonable even on 32bit.

...
> -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32 *data)
>  {
>  	u8 requesttype;
>  	u16 wvalue;
>  	u16 len;
> -	__le32 data;
> +	int res;
> +	__le32 tmp;
> +
> +	if (WARN_ON(unlikely(!data)))
> +		return -EINVAL;
> 

Kill the NULL check - it is a silly coding error.
An OOPS is just as easy to debug.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-26  8:51                         ` David Laight
@ 2021-08-26  9:22                           ` Pavel Skripkin
  2021-08-26  9:27                             ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-26  9:22 UTC (permalink / raw)
  To: David Laight
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On Thu, 26 Aug 2021 08:51:23 +0000
David Laight <David.Laight@ACULAB.COM> wrote:

> From: Pavel Skripkin <paskripkin@gmail.com>
> > Sent: 24 August 2021 08:28
> > 
> > _rtw_read32 function can fail in case of usb transfer failure. But
> > previous function prototype wasn't designed to return an error to
> > caller. It can cause a lot uninit value bugs all across the driver
> > code, since rtw_read32() returns local stack variable to caller.
> > 
> > Fix it by changing the prototype of this function. Now it returns an
> > int: 0 on success, negative error value on failure and callers
> > should pass the pointer to storage location for register value.
> 
> Pretty horrid API interface.
> Functions like readl() - which can fail just return ~0u and let
> the caller worry about whether that causes serious grief.
> 
> You could make all the read functions return __u64 and return ~0ull
> on error.
> Testing for (value & 1ull << 63) will be reasonable even on 32bit.
> 

I am not the best at API related questions, so can you, please,
explain why your approach is better? 

As I can see, most of the drivers in usb/ directory use smth like this
interface for private reading funcions. We anyway creating tmp variable
(but 64 bit _always_) and checking for mistery error, which we cannot
pass up to callers.

Sorry, if it's _too_ dumb question, but I really can't get your
point....



 

> ...
> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
> > *data) {
> >  	u8 requesttype;
> >  	u16 wvalue;
> >  	u16 len;
> > -	__le32 data;
> > +	int res;
> > +	__le32 tmp;
> > +
> > +	if (WARN_ON(unlikely(!data)))
> > +		return -EINVAL;
> > 
> 
> Kill the NULL check - it is a silly coding error.
> An OOPS is just as easy to debug.
> 


I don't think that one single driver should kill the whole system. It's
100% an error, but kernel can recover from it (for example disconnect
the driver, since it's broken).


AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
Correct me, if I am wrong




With regards,
Pavel Skripkin



^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-26  9:22                           ` Pavel Skripkin
@ 2021-08-26  9:27                             ` Pavel Skripkin
  2021-08-26 10:22                               ` David Laight
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-26  9:27 UTC (permalink / raw)
  To: David Laight
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On 8/26/21 12:22 PM, Pavel Skripkin wrote:
> On Thu, 26 Aug 2021 08:51:23 +0000
> David Laight <David.Laight@ACULAB.COM> wrote:
> 
>> From: Pavel Skripkin <paskripkin@gmail.com>
>> > Sent: 24 August 2021 08:28
>> > 
>> > _rtw_read32 function can fail in case of usb transfer failure. But
>> > previous function prototype wasn't designed to return an error to
>> > caller. It can cause a lot uninit value bugs all across the driver
>> > code, since rtw_read32() returns local stack variable to caller.
>> > 
>> > Fix it by changing the prototype of this function. Now it returns an
>> > int: 0 on success, negative error value on failure and callers
>> > should pass the pointer to storage location for register value.
>> 
>> Pretty horrid API interface.
>> Functions like readl() - which can fail just return ~0u and let
>> the caller worry about whether that causes serious grief.
>> 
>> You could make all the read functions return __u64 and return ~0ull
>> on error.
>> Testing for (value & 1ull << 63) will be reasonable even on 32bit.
>> 
> 
> I am not the best at API related questions, so can you, please,
> explain why your approach is better?
> 
> As I can see, most of the drivers in usb/ directory use smth like this
> interface for private reading funcions. We anyway creating tmp variable
> (but 64 bit _always_) and checking for mistery error, which we cannot
> pass up to callers.
> 
> Sorry, if it's _too_ dumb question, but I really can't get your
> point....
> 
> 
> 
>   
> 
>> ...
>> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
>> > *data) {
>> >  	u8 requesttype;
>> >  	u16 wvalue;
>> >  	u16 len;
>> > -	__le32 data;
>> > +	int res;
>> > +	__le32 tmp;
>> > +
>> > +	if (WARN_ON(unlikely(!data)))
>> > +		return -EINVAL;
>> > 
>> 
>> Kill the NULL check - it is a silly coding error.
>> An OOPS is just as easy to debug.
>> 
> 
> 
> I don't think that one single driver should kill the whole system. It's
> 100% an error, but kernel can recover from it (for example disconnect
> the driver, since it's broken).
> 
> 
> AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
> Correct me, if I am wrong
> 
Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for 
confusion. My point is "we should not let the box boom".





With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* RE: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-26  8:27                           ` Pavel Skripkin
@ 2021-08-26 10:19                             ` David Laight
  2021-08-26 11:21                               ` Dan Carpenter
  0 siblings, 1 reply; 118+ messages in thread
From: David Laight @ 2021-08-26 10:19 UTC (permalink / raw)
  To: 'Pavel Skripkin'
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

From: Pavel Skripkin
> Sent: 26 August 2021 09:28
> 
> On Thu, 26 Aug 2021 08:21:34 +0000
> David Laight <David.Laight@ACULAB.COM> wrote:
> 
> > From: Pavel Skripkin
> > > Sent: 24 August 2021 08:27
> > >
> > > _rtw_read8 function can fail in case of usb transfer failure. But
> > > previous function prototype wasn't designed to return an error to
> > > caller. It can cause a lot uninit value bugs all across the driver
> > > code, since rtw_read8() returns local stack variable to caller.
> > >
> > > Fix it by changing the prototype of this function. Now it returns an
> > > int: 0 on success, negative error value on failure and callers
> > > should pass the pointer to storage location for register value.
> >
> > ...
> > > +		len += snprintf(page + len, count - len,
> > > "rtw_read8(0x%x)=0x%x\n",
> > > +				proc_get_read_addr, (u8) tmp);
> >
> > That is broken.
> >
> 
> Don't get it, sorry. Previous code did exactly the same thing, but
> didn't check if read() was successful.

Look up the return value of snprintf().

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 118+ messages in thread

* RE: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-26  9:27                             ` Pavel Skripkin
@ 2021-08-26 10:22                               ` David Laight
  2021-08-26 10:55                                 ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: David Laight @ 2021-08-26 10:22 UTC (permalink / raw)
  To: 'Pavel Skripkin'
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

From: Pavel Skripkin
> Sent: 26 August 2021 10:28
> 
> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
> > On Thu, 26 Aug 2021 08:51:23 +0000
> > David Laight <David.Laight@ACULAB.COM> wrote:
...
> >> ...
> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
> >> > *data) {
> >> >  	u8 requesttype;
> >> >  	u16 wvalue;
> >> >  	u16 len;
> >> > -	__le32 data;
> >> > +	int res;
> >> > +	__le32 tmp;
> >> > +
> >> > +	if (WARN_ON(unlikely(!data)))
> >> > +		return -EINVAL;
> >> >
> >>
> >> Kill the NULL check - it is a silly coding error.
> >> An OOPS is just as easy to debug.
> >>
> >
> >
> > I don't think that one single driver should kill the whole system. It's
> > 100% an error, but kernel can recover from it (for example disconnect
> > the driver, since it's broken).
> >
> >
> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
> > Correct me, if I am wrong
> >
> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
> confusion. My point is "we should not let the box boom".


There is no point checking for NULL that just can't happen.
In this case all the callers will pass the address of a local.
There really is no point checking.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 2/6] staging: r8188eu: add helper macro for printing registers
  2021-08-24  7:27                       ` [PATCH v3 2/6] staging: r8188eu: add helper macro for printing registers Pavel Skripkin
@ 2021-08-26 10:37                         ` Greg KH
  0 siblings, 0 replies; 118+ messages in thread
From: Greg KH @ 2021-08-26 10:37 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry.Finger, phil, straube.linux, fmdefrancesco, linux-staging,
	linux-kernel

On Tue, Aug 24, 2021 at 10:27:20AM +0300, Pavel Skripkin wrote:
> There are a lof of places, where DBG_88E() is used to print register
> value. Since following patches change _rtw_read*() family
> prototypes, we can wrap printing registers into useful macro to avoid
> open-coding error checking like this:
> 
> 	u32 tmp;
> 	if (!rtw_read(&tmp))
> 		DBG("reg = %d\n", tmp);
> 
> So, added DBG_88E_REG{8,16,32} macros for printing register values.

No, please work to remove these messy things, do not add new ones.

Why is this ever needed?  And if it is, use the correct in-kernel debug
functions please.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 1/6] staging: r8188eu: remove {read,write}_macreg
  2021-08-24  7:27                       ` [PATCH v3 1/6] staging: r8188eu: remove {read,write}_macreg Pavel Skripkin
@ 2021-08-26 10:39                         ` Greg KH
  2021-08-26 10:40                         ` Greg KH
  1 sibling, 0 replies; 118+ messages in thread
From: Greg KH @ 2021-08-26 10:39 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry.Finger, phil, straube.linux, fmdefrancesco, linux-staging,
	linux-kernel

On Tue, Aug 24, 2021 at 10:27:13AM +0300, Pavel Skripkin wrote:
> These 2 functions are unused, so they can be simply removed
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
>  drivers/staging/r8188eu/core/rtw_mp.c    | 39 ------------------------
>  drivers/staging/r8188eu/include/rtw_mp.h |  2 --
>  2 files changed, 41 deletions(-)

write_macreg_hdl and the read version can also be removed, right?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 1/6] staging: r8188eu: remove {read,write}_macreg
  2021-08-24  7:27                       ` [PATCH v3 1/6] staging: r8188eu: remove {read,write}_macreg Pavel Skripkin
  2021-08-26 10:39                         ` Greg KH
@ 2021-08-26 10:40                         ` Greg KH
  1 sibling, 0 replies; 118+ messages in thread
From: Greg KH @ 2021-08-26 10:40 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry.Finger, phil, straube.linux, fmdefrancesco, linux-staging,
	linux-kernel

On Tue, Aug 24, 2021 at 10:27:13AM +0300, Pavel Skripkin wrote:
> These 2 functions are unused, so they can be simply removed
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
>  drivers/staging/r8188eu/core/rtw_mp.c    | 39 ------------------------
>  drivers/staging/r8188eu/include/rtw_mp.h |  2 --
>  2 files changed, 41 deletions(-)

I took this one patch of this series, please redo the rest of them and
resend.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-24  7:27                       ` [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16 Pavel Skripkin
  2021-08-25  4:35                         ` Fabio M. De Francesco
@ 2021-08-26 10:50                         ` Greg KH
  2021-08-26 10:58                           ` Pavel Skripkin
  1 sibling, 1 reply; 118+ messages in thread
From: Greg KH @ 2021-08-26 10:50 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry.Finger, phil, straube.linux, fmdefrancesco, linux-staging,
	linux-kernel

On Tue, Aug 24, 2021 at 10:27:35AM +0300, Pavel Skripkin wrote:
> _rtw_read16 function can fail in case of usb transfer failure. But
> previous function prototype wasn't designed to return an error to
> caller. It can cause a lot uninit value bugs all across the driver code,
> since rtw_read16() returns local stack variable to caller.
> 
> Fix it by changing the prototype of this function. Now it returns an
> int: 0 on success, negative error value on failure and callers should pass
> the pointer to storage location for register value.
> 
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
> ---
>  drivers/staging/r8188eu/core/rtw_debug.c      |  7 +++-
>  drivers/staging/r8188eu/core/rtw_io.c         |  9 ++---
>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  4 +-
>  drivers/staging/r8188eu/hal/odm_interface.c   |  4 +-
>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 29 +++++++++++----
>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  5 ++-
>  drivers/staging/r8188eu/hal/usb_halinit.c     | 37 ++++++++++++++++---
>  drivers/staging/r8188eu/hal/usb_ops_linux.c   | 22 +++++++++--
>  .../staging/r8188eu/include/odm_interface.h   |  2 +-
>  drivers/staging/r8188eu/include/rtw_io.h      |  6 +--
>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 28 +++++++++++---
>  11 files changed, 115 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
> index 8b7d3eb12bd0..a41675e101ac 100644
> --- a/drivers/staging/r8188eu/core/rtw_debug.c
> +++ b/drivers/staging/r8188eu/core/rtw_debug.c
> @@ -91,7 +91,12 @@ int proc_get_read_reg(char *page, char **start,
>  				proc_get_read_addr, (u8) tmp);
>  		break;
>  	case 2:
> -		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
> +		error = rtw_read16(padapter, proc_get_read_addr, (u16 *) &tmp);
> +		if (error)
> +			return len;
> +
> +		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n",
> +				proc_get_read_addr, (u16) tmp);
>  		break;
>  	case 4:
>  		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
> diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
> index 2714506c8ffb..fd64893c778d 100644
> --- a/drivers/staging/r8188eu/core/rtw_io.c
> +++ b/drivers/staging/r8188eu/core/rtw_io.c
> @@ -45,18 +45,15 @@ int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
>  	return _read8(pintfhdl, addr, data);
>  }
>  
> -u16 _rtw_read16(struct adapter *adapter, u32 addr)
> +int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
>  {
> -	u16 r_val;
>  	struct io_priv *pio_priv = &adapter->iopriv;
>  	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
> -	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
> +	int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
>  
>  	_read16 = pintfhdl->io_ops._read16;

Why do you need this extra pointer abstraction anyway?  Please unwind
that first, which will make this function go away (or get easier to
understand at the least...)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-26 10:22                               ` David Laight
@ 2021-08-26 10:55                                 ` Pavel Skripkin
  2021-08-26 10:59                                   ` David Laight
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-26 10:55 UTC (permalink / raw)
  To: David Laight
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On 8/26/21 1:22 PM, David Laight wrote:
> From: Pavel Skripkin
>> Sent: 26 August 2021 10:28
>> 
>> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
>> > On Thu, 26 Aug 2021 08:51:23 +0000
>> > David Laight <David.Laight@ACULAB.COM> wrote:
> ...
>> >> ...
>> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
>> >> > *data) {
>> >> >  	u8 requesttype;
>> >> >  	u16 wvalue;
>> >> >  	u16 len;
>> >> > -	__le32 data;
>> >> > +	int res;
>> >> > +	__le32 tmp;
>> >> > +
>> >> > +	if (WARN_ON(unlikely(!data)))
>> >> > +		return -EINVAL;
>> >> >
>> >>
>> >> Kill the NULL check - it is a silly coding error.
>> >> An OOPS is just as easy to debug.
>> >>
>> >
>> >
>> > I don't think that one single driver should kill the whole system. It's
>> > 100% an error, but kernel can recover from it (for example disconnect
>> > the driver, since it's broken).
>> >
>> >
>> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
>> > Correct me, if I am wrong
>> >
>> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
>> confusion. My point is "we should not let the box boom".
> 
> 
> There is no point checking for NULL that just can't happen.
> In this case all the callers will pass the address of a local.
> There really is no point checking.
> 

We not always read in local variable, there are few places, where we 
read into passed buffer.



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 4/6] staging: r8188eu: add error handling of rtw_read16
  2021-08-26 10:50                         ` Greg KH
@ 2021-08-26 10:58                           ` Pavel Skripkin
  0 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-26 10:58 UTC (permalink / raw)
  To: Greg KH
  Cc: Larry.Finger, phil, straube.linux, fmdefrancesco, linux-staging,
	linux-kernel

On 8/26/21 1:50 PM, Greg KH wrote:
> On Tue, Aug 24, 2021 at 10:27:35AM +0300, Pavel Skripkin wrote:
>> _rtw_read16 function can fail in case of usb transfer failure. But
>> previous function prototype wasn't designed to return an error to
>> caller. It can cause a lot uninit value bugs all across the driver code,
>> since rtw_read16() returns local stack variable to caller.
>> 
>> Fix it by changing the prototype of this function. Now it returns an
>> int: 0 on success, negative error value on failure and callers should pass
>> the pointer to storage location for register value.
>> 
>> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
>> ---
>>  drivers/staging/r8188eu/core/rtw_debug.c      |  7 +++-
>>  drivers/staging/r8188eu/core/rtw_io.c         |  9 ++---
>>  drivers/staging/r8188eu/core/rtw_mp_ioctl.c   |  4 +-
>>  drivers/staging/r8188eu/hal/odm_interface.c   |  4 +-
>>  .../staging/r8188eu/hal/rtl8188e_hal_init.c   | 29 +++++++++++----
>>  drivers/staging/r8188eu/hal/rtl8188e_phycfg.c |  5 ++-
>>  drivers/staging/r8188eu/hal/usb_halinit.c     | 37 ++++++++++++++++---
>>  drivers/staging/r8188eu/hal/usb_ops_linux.c   | 22 +++++++++--
>>  .../staging/r8188eu/include/odm_interface.h   |  2 +-
>>  drivers/staging/r8188eu/include/rtw_io.h      |  6 +--
>>  drivers/staging/r8188eu/os_dep/ioctl_linux.c  | 28 +++++++++++---
>>  11 files changed, 115 insertions(+), 38 deletions(-)
>> 
>> diff --git a/drivers/staging/r8188eu/core/rtw_debug.c b/drivers/staging/r8188eu/core/rtw_debug.c
>> index 8b7d3eb12bd0..a41675e101ac 100644
>> --- a/drivers/staging/r8188eu/core/rtw_debug.c
>> +++ b/drivers/staging/r8188eu/core/rtw_debug.c
>> @@ -91,7 +91,12 @@ int proc_get_read_reg(char *page, char **start,
>>  				proc_get_read_addr, (u8) tmp);
>>  		break;
>>  	case 2:
>> -		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
>> +		error = rtw_read16(padapter, proc_get_read_addr, (u16 *) &tmp);
>> +		if (error)
>> +			return len;
>> +
>> +		len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n",
>> +				proc_get_read_addr, (u16) tmp);
>>  		break;
>>  	case 4:
>>  		len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
>> diff --git a/drivers/staging/r8188eu/core/rtw_io.c b/drivers/staging/r8188eu/core/rtw_io.c
>> index 2714506c8ffb..fd64893c778d 100644
>> --- a/drivers/staging/r8188eu/core/rtw_io.c
>> +++ b/drivers/staging/r8188eu/core/rtw_io.c
>> @@ -45,18 +45,15 @@ int __must_check _rtw_read8(struct adapter *adapter, u32 addr, u8 *data)
>>  	return _read8(pintfhdl, addr, data);
>>  }
>>  
>> -u16 _rtw_read16(struct adapter *adapter, u32 addr)
>> +int __must_check _rtw_read16(struct adapter *adapter, u32 addr, u16 *data)
>>  {
>> -	u16 r_val;
>>  	struct io_priv *pio_priv = &adapter->iopriv;
>>  	struct	intf_hdl		*pintfhdl = &pio_priv->intf;
>> -	u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
>> +	int (*_read16)(struct intf_hdl *pintfhdl, u32 addr, u16 *data);
>>  
>>  	_read16 = pintfhdl->io_ops._read16;
> 
> Why do you need this extra pointer abstraction anyway?  Please unwind
> that first, which will make this function go away (or get easier to
> understand at the least...)
> 
It was there before my changes :) I had a plan to clean up DBG macros 
and this abstraction after adding error handling...


If you feel, that these clean up are needed before error handling, I can 
add them to this series :) Anyway, some of them are already in my local 
tree



With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* RE: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-26 10:55                                 ` Pavel Skripkin
@ 2021-08-26 10:59                                   ` David Laight
  2021-08-26 20:03                                     ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: David Laight @ 2021-08-26 10:59 UTC (permalink / raw)
  To: 'Pavel Skripkin'
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

From: Pavel Skripkin
> Sent: 26 August 2021 11:55
> 
> On 8/26/21 1:22 PM, David Laight wrote:
> > From: Pavel Skripkin
> >> Sent: 26 August 2021 10:28
> >>
> >> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
> >> > On Thu, 26 Aug 2021 08:51:23 +0000
> >> > David Laight <David.Laight@ACULAB.COM> wrote:
> > ...
> >> >> ...
> >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
> >> >> > *data) {
> >> >> >  	u8 requesttype;
> >> >> >  	u16 wvalue;
> >> >> >  	u16 len;
> >> >> > -	__le32 data;
> >> >> > +	int res;
> >> >> > +	__le32 tmp;
> >> >> > +
> >> >> > +	if (WARN_ON(unlikely(!data)))
> >> >> > +		return -EINVAL;
> >> >> >
> >> >>
> >> >> Kill the NULL check - it is a silly coding error.
> >> >> An OOPS is just as easy to debug.
> >> >>
> >> >
> >> >
> >> > I don't think that one single driver should kill the whole system. It's
> >> > 100% an error, but kernel can recover from it (for example disconnect
> >> > the driver, since it's broken).
> >> >
> >> >
> >> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
> >> > Correct me, if I am wrong
> >> >
> >> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
> >> confusion. My point is "we should not let the box boom".
> >
> >
> > There is no point checking for NULL that just can't happen.
> > In this case all the callers will pass the address of a local.
> > There really is no point checking.
> >
> 
> We not always read in local variable, there are few places, where we
> read into passed buffer.

It is still a very local coding bug.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-25 17:11                                     ` Nick Desaulniers
@ 2021-08-26 11:08                                       ` Dan Carpenter
  0 siblings, 0 replies; 118+ messages in thread
From: Dan Carpenter @ 2021-08-26 11:08 UTC (permalink / raw)
  To: Nick Desaulniers
  Cc: Pavel Skripkin, kernel test robot, Larry.Finger, phil, gregkh,
	straube.linux, fmdefrancesco, clang-built-linux, kbuild-all,
	linux-staging, linux-kernel

On Wed, Aug 25, 2021 at 10:11:45AM -0700, Nick Desaulniers wrote:
> On Wed, Aug 25, 2021 at 6:44 AM Pavel Skripkin <paskripkin@gmail.com> wrote:
> >
> > On 8/25/21 4:34 PM, Dan Carpenter wrote:
> > > On Wed, Aug 25, 2021 at 04:02:26PM +0300, Pavel Skripkin wrote:
> > >> > This is not related to your patch.  Ignore it.
> > >> >
> > >> >
> > >> > > > vim +2022 drivers/staging/r8188eu/hal/usb_halinit.c
> > >> > > >
> > >> > >
> > >> > > >    2020                case HW_VAR_BCN_VALID:
> > >> > > >    2021                        /* BCN_VALID, BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */
> > >> > > > > 2022                         u8 tmp;
> > >> > >
> > >> > > Hm, I don't know anything about ARM compilers, so should I wrap this code
> > >> > > block with {}?
> > >> >
> > >> > Yep.
> > >> >
> > >> > >
> > >> > > My local gcc 11.1.1 (x86_64) does not produce any warnings/errors
> > >> > >
> > >> >
> > >> > You should figure out whats up with that because it shouldn't compile
> > >> > with the gcc options that the kernel uses.
> > >> >
> > >>
> > >> AFAIK, at least 2 guys except me in this CC list compiled my series without
> > >> errors/warnings. Maybe, staging tree is missing some Makefile updates?
> > >>
> > >>
> > >> I'll resend series this evening anyway, but this is strange....
> > >
> > > Hm...  In my version of GCC the error is:
> > >
> > > drivers/staging/r8188eu/hal/usb_halinit.c:1870:3: error: a label can only be part of a statement and a declaration is not a statement
> > >
> > > That's a different error from what I was expecting.  It's caused by
> > > having a declaration directly after a case statement.  The warning that
> > > I was expecting was from -Wdeclaration-after-statement and it looks
> > > like this:
> > >
> > > warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
> > >
> > > You really should try investigate why this compiles for you because
> > > something is going wrong.  It should not build without a warning.
> > >
> >
> > Looks like it's bug in gcc 11.1.1. I've rebuilt this module with gcc 10
> > (gcc-10 (SUSE Linux) 10.3.1 20210707 [revision
> > 048117e16c77f82598fca9af585500572d46ad73]) and build fails with error
> > described above
> >
> >
> > My default gcc is
> >
> > gcc (SUSE Linux) 11.1.1 20210721 [revision
> > 076930b9690ac3564638636f6b13bbb6bc608aea]
> >
> >
> > Any idea? :)
> 
> The original report said the build was with clang-14, which is near
> top of tree and unreleased. It's possible that that build had a bug
> that hopefully was reverted.

No, Clang is right to refuse to build the code.  It's GCC 11.1.1 which
is wrong because it allows it.  I'm not C language expert but we're
using the -Wdeclaration-after-statement because we don't want this.

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 3/6] staging: r8188eu: add error handling of rtw_read8
  2021-08-26 10:19                             ` David Laight
@ 2021-08-26 11:21                               ` Dan Carpenter
  2021-08-27  8:14                                 ` David Laight
  0 siblings, 1 reply; 118+ messages in thread
From: Dan Carpenter @ 2021-08-26 11:21 UTC (permalink / raw)
  To: David Laight
  Cc: 'Pavel Skripkin',
	Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On Thu, Aug 26, 2021 at 10:19:40AM +0000, David Laight wrote:
> From: Pavel Skripkin
> > Sent: 26 August 2021 09:28
> > 
> > On Thu, 26 Aug 2021 08:21:34 +0000
> > David Laight <David.Laight@ACULAB.COM> wrote:
> > 
> > > From: Pavel Skripkin
> > > > Sent: 24 August 2021 08:27
> > > >
> > > > _rtw_read8 function can fail in case of usb transfer failure. But
> > > > previous function prototype wasn't designed to return an error to
> > > > caller. It can cause a lot uninit value bugs all across the driver
> > > > code, since rtw_read8() returns local stack variable to caller.
> > > >
> > > > Fix it by changing the prototype of this function. Now it returns an
> > > > int: 0 on success, negative error value on failure and callers
> > > > should pass the pointer to storage location for register value.
> > >
> > > ...
> > > > +		len += snprintf(page + len, count - len,
> > > > "rtw_read8(0x%x)=0x%x\n",
> > > > +				proc_get_read_addr, (u8) tmp);
> > >
> > > That is broken.
> > >
> > 
> > Don't get it, sorry. Previous code did exactly the same thing, but
> > didn't check if read() was successful.
> 
> Look up the return value of snprintf().
> 

It's hard to understand what you are saying.  I think you are confusing
libc snprintf with the kernel snprintf?  In libc the snprintf function
can return negatives but in the kernel it cannot.  This is not going
to change.  Any code which checks for negative snprintf returns in the
kernel is wrong and should be fixed.

Anyway, the code works fine.  snprintf here is going to return a number
between 18-32 range.  It's not going to overflow the PAGE_SIZE buffer.

It would be nicer to use scnprint() but that's an unrelated patch.

Also this is all dead code.  It needs to be converted to sysfs.  The
caller is ifdeffed out because it doesn't compile.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-26 10:59                                   ` David Laight
@ 2021-08-26 20:03                                     ` Pavel Skripkin
  2021-08-27  7:12                                       ` gregkh
  0 siblings, 1 reply; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-26 20:03 UTC (permalink / raw)
  To: David Laight
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On 8/26/21 1:59 PM, David Laight wrote:
> From: Pavel Skripkin
>> Sent: 26 August 2021 11:55
>> 
>> On 8/26/21 1:22 PM, David Laight wrote:
>> > From: Pavel Skripkin
>> >> Sent: 26 August 2021 10:28
>> >>
>> >> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
>> >> > On Thu, 26 Aug 2021 08:51:23 +0000
>> >> > David Laight <David.Laight@ACULAB.COM> wrote:
>> > ...
>> >> >> ...
>> >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
>> >> >> > *data) {
>> >> >> >  	u8 requesttype;
>> >> >> >  	u16 wvalue;
>> >> >> >  	u16 len;
>> >> >> > -	__le32 data;
>> >> >> > +	int res;
>> >> >> > +	__le32 tmp;
>> >> >> > +
>> >> >> > +	if (WARN_ON(unlikely(!data)))
>> >> >> > +		return -EINVAL;
>> >> >> >
>> >> >>
>> >> >> Kill the NULL check - it is a silly coding error.
>> >> >> An OOPS is just as easy to debug.
>> >> >>
>> >> >
>> >> >
>> >> > I don't think that one single driver should kill the whole system. It's
>> >> > 100% an error, but kernel can recover from it (for example disconnect
>> >> > the driver, since it's broken).
>> >> >
>> >> >
>> >> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
>> >> > Correct me, if I am wrong
>> >> >
>> >> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
>> >> confusion. My point is "we should not let the box boom".
>> >
>> >
>> > There is no point checking for NULL that just can't happen.
>> > In this case all the callers will pass the address of a local.
>> > There really is no point checking.
>> >
>> 
>> We not always read in local variable, there are few places, where we
>> read into passed buffer.
> 
> It is still a very local coding bug.
> 
> 	David
> 

Sure, but is defensive programming so bad?


Greg, what your opinion about this NULL check?




With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-26 20:03                                     ` Pavel Skripkin
@ 2021-08-27  7:12                                       ` gregkh
  2021-08-27  7:16                                         ` Pavel Skripkin
  0 siblings, 1 reply; 118+ messages in thread
From: gregkh @ 2021-08-27  7:12 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: David Laight, Larry.Finger, phil, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On Thu, Aug 26, 2021 at 11:03:04PM +0300, Pavel Skripkin wrote:
> On 8/26/21 1:59 PM, David Laight wrote:
> > From: Pavel Skripkin
> > > Sent: 26 August 2021 11:55
> > > 
> > > On 8/26/21 1:22 PM, David Laight wrote:
> > > > From: Pavel Skripkin
> > > >> Sent: 26 August 2021 10:28
> > > >>
> > > >> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
> > > >> > On Thu, 26 Aug 2021 08:51:23 +0000
> > > >> > David Laight <David.Laight@ACULAB.COM> wrote:
> > > > ...
> > > >> >> ...
> > > >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
> > > >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
> > > >> >> > *data) {
> > > >> >> >  	u8 requesttype;
> > > >> >> >  	u16 wvalue;
> > > >> >> >  	u16 len;
> > > >> >> > -	__le32 data;
> > > >> >> > +	int res;
> > > >> >> > +	__le32 tmp;
> > > >> >> > +
> > > >> >> > +	if (WARN_ON(unlikely(!data)))
> > > >> >> > +		return -EINVAL;
> > > >> >> >
> > > >> >>
> > > >> >> Kill the NULL check - it is a silly coding error.
> > > >> >> An OOPS is just as easy to debug.
> > > >> >>
> > > >> >
> > > >> >
> > > >> > I don't think that one single driver should kill the whole system. It's
> > > >> > 100% an error, but kernel can recover from it (for example disconnect
> > > >> > the driver, since it's broken).
> > > >> >
> > > >> >
> > > >> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
> > > >> > Correct me, if I am wrong
> > > >> >
> > > >> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
> > > >> confusion. My point is "we should not let the box boom".
> > > >
> > > >
> > > > There is no point checking for NULL that just can't happen.
> > > > In this case all the callers will pass the address of a local.
> > > > There really is no point checking.
> > > >
> > > 
> > > We not always read in local variable, there are few places, where we
> > > read into passed buffer.
> > 
> > It is still a very local coding bug.
> > 
> > 	David
> > 
> 
> Sure, but is defensive programming so bad?

Yes it is, for when it is not needed.

> Greg, what your opinion about this NULL check?

Never check for things that you know are not going to happen.  Otherwise
the kernel would just be full of pointless checks everywhere.

And why are you waiting for me to tell you this?  Why do you not believe
David?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 5/6] staging: r8188eu: add error handling of rtw_read32
  2021-08-27  7:12                                       ` gregkh
@ 2021-08-27  7:16                                         ` Pavel Skripkin
  0 siblings, 0 replies; 118+ messages in thread
From: Pavel Skripkin @ 2021-08-27  7:16 UTC (permalink / raw)
  To: gregkh
  Cc: David Laight, Larry.Finger, phil, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On 8/27/21 10:12 AM, gregkh@linuxfoundation.org wrote:
> On Thu, Aug 26, 2021 at 11:03:04PM +0300, Pavel Skripkin wrote:
>> On 8/26/21 1:59 PM, David Laight wrote:
>> > From: Pavel Skripkin
>> > > Sent: 26 August 2021 11:55
>> > > 
>> > > On 8/26/21 1:22 PM, David Laight wrote:
>> > > > From: Pavel Skripkin
>> > > >> Sent: 26 August 2021 10:28
>> > > >>
>> > > >> On 8/26/21 12:22 PM, Pavel Skripkin wrote:
>> > > >> > On Thu, 26 Aug 2021 08:51:23 +0000
>> > > >> > David Laight <David.Laight@ACULAB.COM> wrote:
>> > > > ...
>> > > >> >> ...
>> > > >> >> > -static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
>> > > >> >> > +static int usb_read32(struct intf_hdl *pintfhdl, u32 addr, u32
>> > > >> >> > *data) {
>> > > >> >> >  	u8 requesttype;
>> > > >> >> >  	u16 wvalue;
>> > > >> >> >  	u16 len;
>> > > >> >> > -	__le32 data;
>> > > >> >> > +	int res;
>> > > >> >> > +	__le32 tmp;
>> > > >> >> > +
>> > > >> >> > +	if (WARN_ON(unlikely(!data)))
>> > > >> >> > +		return -EINVAL;
>> > > >> >> >
>> > > >> >>
>> > > >> >> Kill the NULL check - it is a silly coding error.
>> > > >> >> An OOPS is just as easy to debug.
>> > > >> >>
>> > > >> >
>> > > >> >
>> > > >> > I don't think that one single driver should kill the whole system. It's
>> > > >> > 100% an error, but kernel can recover from it (for example disconnect
>> > > >> > the driver, since it's broken).
>> > > >> >
>> > > >> >
>> > > >> > AFIAK, Greg and Linus do not like BUG_ONs in recoverable state...
>> > > >> > Correct me, if I am wrong
>> > > >> >
>> > > >> Oops, I thought about BUG_ON() instead of WARN_ON(), sorry for
>> > > >> confusion. My point is "we should not let the box boom".
>> > > >
>> > > >
>> > > > There is no point checking for NULL that just can't happen.
>> > > > In this case all the callers will pass the address of a local.
>> > > > There really is no point checking.
>> > > >
>> > > 
>> > > We not always read in local variable, there are few places, where we
>> > > read into passed buffer.
>> > 
>> > It is still a very local coding bug.
>> > 
>> > 	David
>> > 
>> 
>> Sure, but is defensive programming so bad?
> 
> Yes it is, for when it is not needed.
> 
>> Greg, what your opinion about this NULL check?
> 
> Never check for things that you know are not going to happen.  Otherwise
> the kernel would just be full of pointless checks everywhere.
> 
> And why are you waiting for me to tell you this?  Why do you not believe
> David?
> 


Just wanted to hear more opinions on this check. I believe David, but 
opinions of other people are important too, IMO




With regards,
Pavel Skripkin

^ permalink raw reply	[flat|nested] 118+ messages in thread

* Re: [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs
  2021-08-24  7:25                     ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Pavel Skripkin
                                         ` (6 preceding siblings ...)
  2021-08-25 10:13                       ` [PATCH v3 0/6] staging: r8188eu: avoid uninit value bugs Fabio M. De Francesco
@ 2021-08-27  7:49                       ` Kari Argillander
  2021-08-27  7:52                         ` Pavel Skripkin
  7 siblings, 1 reply; 118+ messages in thread
From: Kari Argillander @ 2021-08-27  7:49 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Larry.Finger, phil, gregkh, straube.linux, fmdefrancesco,
	linux-staging, linux-kernel

On Tue, Aug 24, 2021 at 10:25:45AM +0300, Pavel Skripkin wrote:
> Hi, Greg, Larry and Phillip!
> 
> I noticed, that new staging driver was added like 3 weeks ago and I decided
> to look at the code, because drivers in staging directory are always buggy.
> 
> The first thing I noticed is *no one* was checking read operations result, but
> it can fail and driver may start writing random stack values into registers. It
> can cause driver misbehavior or device misbehavior.
> 
> To avoid this type of bugs, i've changed rtw_read* API. Now all rtw_read
> funtions return an error, when something went wrong with usb transfer.
> 
> It helps callers to break/return earlier and don't write random values to
> registers or to rely on random values.
> 
> 
> v2 -> v3:

Hi Pavel.

If v4 is needed can you please send it without replying to old message.
This thread is so hard to follow because always new version is answer to
old subject. This depens a little bit how you setup your email, but some
of us is grouping all emails in same thread and this thread is out of
control :D

Thanks
Kari Argillander

>   1. Fixed OOPS in usb_read32(), caused by writing to u32 **
>   2. Fixed style in rtw_read32, rtw_read16 and rtw_read8 (Suggested by Dan)
>   3. Added error hanling when usb_control_msg() returns ret != len
>      NOTE: Dan suggested to add this to usbctrl_vendorreq(), but there is
>      pending series, which will get rid of usb_control_msg(), so (res != len)
>      check can be removed, when Fabio's series will go in
>   4. Removed RFC tag
> 
> v1 -> v2:
>   1. Make rtw_read*() return an error instead of initializing pointer to error
>   2. Split one huge patch to smaller ones for each rtw_read{8,16,32} function
>      changes
>   3. Add new macro for printing register values (It helps to not copy-paste error
>      handling)
>   4. Removed {read,write}_macreg (Suggested by Phillip)
>   5. Rebased on top of staging-next
>   6. Cleaned checkpatch errors and warnings
> 
> 
> Phillip has tested fixed v2 version, AFAIU
> 
> Pavel Skripkin (6):
>   staging: r8188eu: remove {read,write}_macreg
>   staging: r8188eu: add helper macro for printing registers
>   staging: r8188eu: add error handling of rtw_read8
>   staging: r8188eu: add error handling of rtw_read16
>   staging: r8188eu: add error handling of rtw_read32
>   staging: r8188eu: make ReadEFuse return an int
> 
>  drivers/staging/r8188eu/core/rtw_debug.c      |  79 +++-
>  drivers/staging/r8188eu/core/rtw_efuse.c      | 125 +++--
>  drivers/staging/r818