@@ -387,6 +387,8 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
387387 clear_bit (MWIFIEX_IFACE_WORK_DEVICE_DUMP , & card -> work_flags );
388388 clear_bit (MWIFIEX_IFACE_WORK_CARD_RESET , & card -> work_flags );
389389 mwifiex_dbg (adapter , INFO , "%s, successful\n" , __func__ );
390+
391+ card -> pci_reset_ongoing = true;
390392}
391393
392394/*
@@ -415,6 +417,8 @@ static void mwifiex_pcie_reset_done(struct pci_dev *pdev)
415417 dev_err (& pdev -> dev , "reinit failed: %d\n" , ret );
416418 else
417419 mwifiex_dbg (adapter , INFO , "%s, successful\n" , __func__ );
420+
421+ card -> pci_reset_ongoing = false;
418422}
419423
420424static const struct pci_error_handlers mwifiex_pcie_err_handler = {
@@ -3005,7 +3009,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
30053009 int ret ;
30063010 u32 fw_status ;
30073011
3008- cancel_work_sync (& card -> work );
3012+ /* Perform the cancel_work_sync() only when we're not resetting
3013+ * the card. It's because that function never returns if we're
3014+ * in reset path. If we're here when resetting the card, it means
3015+ * that we failed to reset the card (reset failure path).
3016+ */
3017+ if (!card -> pci_reset_ongoing ) {
3018+ mwifiex_dbg (adapter , MSG , "performing cancel_work_sync()...\n" );
3019+ cancel_work_sync (& card -> work );
3020+ mwifiex_dbg (adapter , MSG , "cancel_work_sync() done\n" );
3021+ } else {
3022+ mwifiex_dbg (adapter , MSG ,
3023+ "skipped cancel_work_sync() because we're in card reset failure path\n" );
3024+ }
30093025
30103026 ret = mwifiex_read_reg (adapter , reg -> fw_status , & fw_status );
30113027 if (fw_status == FIRMWARE_READY_PCIE ) {
0 commit comments