Commit 419b4a14 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

brcmfmac: properly check for bus register errors

The brcmfmac driver ignores any errors on initialization with the
different busses by deferring the initialization to a workqueue and
ignoring all possible errors that might happen.  Fix up all of this by
only allowing the module to load if all bus registering worked properly.

Cc: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210503115736.2104747-70-gregkh@linuxfoundation.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 30a35094
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -1217,13 +1217,9 @@ static struct sdio_driver brcmf_sdmmc_driver = {
	},
};

void brcmf_sdio_register(void)
int brcmf_sdio_register(void)
{
	int ret;

	ret = sdio_register_driver(&brcmf_sdmmc_driver);
	if (ret)
		brcmf_err("sdio_register_driver failed: %d\n", ret);
	return sdio_register_driver(&brcmf_sdmmc_driver);
}

void brcmf_sdio_exit(void)
+17 −2
Original line number Diff line number Diff line
@@ -275,11 +275,26 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len);

#ifdef CONFIG_BRCMFMAC_SDIO
void brcmf_sdio_exit(void);
void brcmf_sdio_register(void);
int brcmf_sdio_register(void);
#else
static inline void brcmf_sdio_exit(void) { }
static inline int brcmf_sdio_register(void) { return 0; }
#endif

#ifdef CONFIG_BRCMFMAC_USB
void brcmf_usb_exit(void);
void brcmf_usb_register(void);
int brcmf_usb_register(void);
#else
static inline void brcmf_usb_exit(void) { }
static inline int brcmf_usb_register(void) { return 0; }
#endif

#ifdef CONFIG_BRCMFMAC_PCIE
void brcmf_pcie_exit(void);
int brcmf_pcie_register(void);
#else
static inline void brcmf_pcie_exit(void) { }
static inline int brcmf_pcie_register(void) { return 0; }
#endif

#endif /* BRCMFMAC_BUS_H */
+18 −24
Original line number Diff line number Diff line
@@ -1518,40 +1518,34 @@ void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state)
	}
}

static void brcmf_driver_register(struct work_struct *work)
{
#ifdef CONFIG_BRCMFMAC_SDIO
	brcmf_sdio_register();
#endif
#ifdef CONFIG_BRCMFMAC_USB
	brcmf_usb_register();
#endif
#ifdef CONFIG_BRCMFMAC_PCIE
	brcmf_pcie_register();
#endif
}
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);

int __init brcmf_core_init(void)
{
	if (!schedule_work(&brcmf_driver_work))
		return -EBUSY;
	int err;

	err = brcmf_sdio_register();
	if (err)
		return err;

	err = brcmf_usb_register();
	if (err)
		goto error_usb_register;

	err = brcmf_pcie_register();
	if (err)
		goto error_pcie_register;
	return 0;

error_pcie_register:
	brcmf_usb_exit();
error_usb_register:
	brcmf_sdio_exit();
	return err;
}

void __exit brcmf_core_exit(void)
{
	cancel_work_sync(&brcmf_driver_work);

#ifdef CONFIG_BRCMFMAC_SDIO
	brcmf_sdio_exit();
#endif
#ifdef CONFIG_BRCMFMAC_USB
	brcmf_usb_exit();
#endif
#ifdef CONFIG_BRCMFMAC_PCIE
	brcmf_pcie_exit();
#endif
}
+2 −7
Original line number Diff line number Diff line
@@ -2140,15 +2140,10 @@ static struct pci_driver brcmf_pciedrvr = {
};


void brcmf_pcie_register(void)
int brcmf_pcie_register(void)
{
	int err;

	brcmf_dbg(PCIE, "Enter\n");
	err = pci_register_driver(&brcmf_pciedrvr);
	if (err)
		brcmf_err(NULL, "PCIE driver registration failed, err=%d\n",
			  err);
	return pci_register_driver(&brcmf_pciedrvr);
}


+0 −5
Original line number Diff line number Diff line
@@ -11,9 +11,4 @@ struct brcmf_pciedev {
	struct brcmf_pciedev_info *devinfo;
};


void brcmf_pcie_exit(void);
void brcmf_pcie_register(void);


#endif /* BRCMFMAC_PCIE_H */
Loading