提交 419b4a14 编写于 作者: G Greg Kroah-Hartman

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.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 30a35094
...@@ -1217,13 +1217,9 @@ static struct sdio_driver brcmf_sdmmc_driver = { ...@@ -1217,13 +1217,9 @@ static struct sdio_driver brcmf_sdmmc_driver = {
}, },
}; };
void brcmf_sdio_register(void) int brcmf_sdio_register(void)
{ {
int ret; return sdio_register_driver(&brcmf_sdmmc_driver);
ret = sdio_register_driver(&brcmf_sdmmc_driver);
if (ret)
brcmf_err("sdio_register_driver failed: %d\n", ret);
} }
void brcmf_sdio_exit(void) void brcmf_sdio_exit(void)
......
...@@ -275,11 +275,26 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len); ...@@ -275,11 +275,26 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
#ifdef CONFIG_BRCMFMAC_SDIO #ifdef CONFIG_BRCMFMAC_SDIO
void brcmf_sdio_exit(void); 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 #endif
#ifdef CONFIG_BRCMFMAC_USB #ifdef CONFIG_BRCMFMAC_USB
void brcmf_usb_exit(void); 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
#endif /* BRCMFMAC_BUS_H */ #endif /* BRCMFMAC_BUS_H */
...@@ -1518,40 +1518,34 @@ void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state) ...@@ -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) int __init brcmf_core_init(void)
{ {
if (!schedule_work(&brcmf_driver_work)) int err;
return -EBUSY;
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; return 0;
error_pcie_register:
brcmf_usb_exit();
error_usb_register:
brcmf_sdio_exit();
return err;
} }
void __exit brcmf_core_exit(void) void __exit brcmf_core_exit(void)
{ {
cancel_work_sync(&brcmf_driver_work);
#ifdef CONFIG_BRCMFMAC_SDIO
brcmf_sdio_exit(); brcmf_sdio_exit();
#endif
#ifdef CONFIG_BRCMFMAC_USB
brcmf_usb_exit(); brcmf_usb_exit();
#endif
#ifdef CONFIG_BRCMFMAC_PCIE
brcmf_pcie_exit(); brcmf_pcie_exit();
#endif
} }
...@@ -2140,15 +2140,10 @@ static struct pci_driver brcmf_pciedrvr = { ...@@ -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"); brcmf_dbg(PCIE, "Enter\n");
err = pci_register_driver(&brcmf_pciedrvr); return pci_register_driver(&brcmf_pciedrvr);
if (err)
brcmf_err(NULL, "PCIE driver registration failed, err=%d\n",
err);
} }
......
...@@ -11,9 +11,4 @@ struct brcmf_pciedev { ...@@ -11,9 +11,4 @@ struct brcmf_pciedev {
struct brcmf_pciedev_info *devinfo; struct brcmf_pciedev_info *devinfo;
}; };
void brcmf_pcie_exit(void);
void brcmf_pcie_register(void);
#endif /* BRCMFMAC_PCIE_H */ #endif /* BRCMFMAC_PCIE_H */
...@@ -1584,8 +1584,8 @@ void brcmf_usb_exit(void) ...@@ -1584,8 +1584,8 @@ void brcmf_usb_exit(void)
usb_deregister(&brcmf_usbdrvr); usb_deregister(&brcmf_usbdrvr);
} }
void brcmf_usb_register(void) int brcmf_usb_register(void)
{ {
brcmf_dbg(USB, "Enter\n"); brcmf_dbg(USB, "Enter\n");
usb_register(&brcmf_usbdrvr); return usb_register(&brcmf_usbdrvr);
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册