Jelajahi Sumber

qcacld-3.0: Support the case to unload driver successfully

Enforce the chip to complete steps of unloading driver
instead of ASSERTION in the case of powered off.
Enforce the chip to complete pld_pcie_remove to
avoid memory leak.

Change-Id: Iaaadde91dd6329990d28659b283b1be8216a970f
CRs-Fixed: 3590444
Meng Yuan 1 tahun lalu
induk
melakukan
0624aa8b53
3 mengubah file dengan 25 tambahan dan 12 penghapusan
  1. 1 0
      Kbuild
  2. 12 9
      core/hdd/src/wlan_hdd_main.c
  3. 12 3
      core/pld/src/pld_pcie.c

+ 1 - 0
Kbuild

@@ -3790,6 +3790,7 @@ ccflags-$(CONFIG_FEATURE_STATS_EXT) += -DWLAN_FEATURE_STATS_EXT
 ccflags-$(CONFIG_QCACLD_FEATURE_NAN) += -DWLAN_FEATURE_NAN
 ccflags-$(CONFIG_QCACLD_FEATURE_SON) += -DWLAN_FEATURE_SON
 ccflags-$(CONFIG_NDP_SAP_CONCURRENCY_ENABLE) += -DNDP_SAP_CONCURRENCY_ENABLE
+ccflags-$(CONFIG_ENFORCE_PLD_REMOVE) += -DENFORCE_PLD_REMOVE
 
 ifeq ($(CONFIG_DFS_FCC_TYPE4_DURATION_CHECK), y)
 ccflags-$(CONFIG_DFS_FCC_TYPE4_DURATION_CHECK) += -DDFS_FCC_TYPE4_DURATION_CHECK

+ 12 - 9
core/hdd/src/wlan_hdd_main.c

@@ -19845,8 +19845,8 @@ void hdd_driver_unload(void)
 	 * trans are rejected via wlan_hdd_validate_context.
 	 */
 	status = osif_driver_sync_trans_start_wait(&driver_sync);
-	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
-	if (QDF_IS_STATUS_ERROR(status)) {
+	if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) {
+		QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
 		hdd_err("Unable to unload wlan; status:%u", status);
 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
 		return;
@@ -19878,7 +19878,8 @@ void hdd_driver_unload(void)
 	 * Stop the trans before calling unregister_driver as that involves a
 	 * call to pld_remove which in itself is a psoc transaction
 	 */
-	osif_driver_sync_trans_stop(driver_sync);
+	if (driver_sync)
+		osif_driver_sync_trans_stop(driver_sync);
 
 	hdd_distroy_wifi_feature_interface();
 	if (!soft_unload)
@@ -19888,15 +19889,16 @@ void hdd_driver_unload(void)
 	wlan_hdd_unregister_driver();
 
 	status = osif_driver_sync_trans_start_wait(&driver_sync);
-	QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
-	if (QDF_IS_STATUS_ERROR(status)) {
+	if (QDF_IS_STATUS_ERROR(status) && status != -ETIMEDOUT) {
+		QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
 		hdd_err("Unable to unload wlan; status:%u", status);
 		hdd_place_marker(NULL, "UNLOAD FAILURE", NULL);
 		return;
 	}
 
 	osif_driver_sync_unregister();
-	osif_driver_sync_wait_for_ops(driver_sync);
+	if (driver_sync)
+		osif_driver_sync_wait_for_ops(driver_sync);
 
 	hdd_driver_mode_change_unregister();
 	pld_deinit();
@@ -19906,9 +19908,10 @@ void hdd_driver_unload(void)
 	hdd_component_cb_deinit();
 	hdd_deinit();
 
-	osif_driver_sync_trans_stop(driver_sync);
-	osif_driver_sync_destroy(driver_sync);
-
+	if (driver_sync) {
+		osif_driver_sync_trans_stop(driver_sync);
+		osif_driver_sync_destroy(driver_sync);
+	}
 	osif_sync_deinit();
 
 	hdd_qdf_deinit();

+ 12 - 3
core/pld/src/pld_pcie.c

@@ -99,12 +99,19 @@ static void pld_pcie_remove(struct pci_dev *pdev)
 	struct osif_psoc_sync *psoc_sync;
 
 	errno = osif_psoc_sync_trans_start_wait(&pdev->dev, &psoc_sync);
+
+#ifdef ENFORCE_PLD_REMOVE
+	if (errno && errno != -EINVAL)
+		return;
+#else
 	if (errno)
 		return;
+#endif
 
 	osif_psoc_sync_unregister(&pdev->dev);
 
-	osif_psoc_sync_wait_for_ops(psoc_sync);
+	if (psoc_sync)
+		osif_psoc_sync_wait_for_ops(psoc_sync);
 
 	pld_context = pld_get_global_context();
 
@@ -116,8 +123,10 @@ static void pld_pcie_remove(struct pci_dev *pdev)
 	pld_del_dev(pld_context, &pdev->dev);
 
 out:
-	osif_psoc_sync_trans_stop(psoc_sync);
-	osif_psoc_sync_destroy(psoc_sync);
+	if (psoc_sync) {
+		osif_psoc_sync_trans_stop(psoc_sync);
+		osif_psoc_sync_destroy(psoc_sync);
+	}
 }
 
 /**