--- a/drivers/staging/rtl8712/drv_types.h
+++ b/drivers/staging/rtl8712/drv_types.h
@@ -163,6 +163,7 @@ struct _adapter {
 	struct usb_interface *pusb_intf;
 	struct mutex mutex_start;
 	struct completion rtl8712_fw_ready;
+	atomic_t disconnecting;
 };
 
 static inline u8 *myid(struct eeprom_priv *peepriv)
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -589,15 +589,29 @@ put_dev:
  */
 static void r871xu_dev_remove(struct usb_interface *pusb_intf)
 {
-	struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
-	struct usb_device *udev = interface_to_usbdev(pusb_intf);
-	struct _adapter *padapter = netdev_priv(pnetdev);
+	struct net_device *pnetdev;
+	struct usb_device *udev;
+	struct _adapter *padapter = NULL;
+
+	rcu_read_lock();
+	pnetdev = usb_get_intfdata(pusb_intf); 
+	if (pnetdev) {
+		padapter = netdev_priv(pnetdev);
+		if (1 == atomic_inc_return(&padapter->disconnecting))
+			usb_set_intfdata(pusb_intf, NULL);
+		else
+			padapter = NULL;
+	}
+	rcu_read_unlock();
+	if (padapter == NULL)
+		return;
+	synchronize_rcu();
+	udev = interface_to_usbdev(pusb_intf);
 
 	/* never exit with a firmware callback pending */
 	wait_for_completion(&padapter->rtl8712_fw_ready);
 	if (pnetdev->reg_state != NETREG_UNINITIALIZED)
 		unregister_netdev(pnetdev); /* will call netdev_close() */
-	usb_set_intfdata(pusb_intf, NULL);
 	release_firmware(padapter->fw);
 	if (drvpriv.drv_registered)
 		padapter->surprise_removed = true;