Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

+41 -46
+2 -6
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
··· 1217 1217 }, 1218 1218 }; 1219 1219 1220 - void brcmf_sdio_register(void) 1220 + int brcmf_sdio_register(void) 1221 1221 { 1222 - int ret; 1223 - 1224 - ret = sdio_register_driver(&brcmf_sdmmc_driver); 1225 - if (ret) 1226 - brcmf_err("sdio_register_driver failed: %d\n", ret); 1222 + return sdio_register_driver(&brcmf_sdmmc_driver); 1227 1223 } 1228 1224 1229 1225 void brcmf_sdio_exit(void)
+17 -2
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
··· 275 275 276 276 #ifdef CONFIG_BRCMFMAC_SDIO 277 277 void brcmf_sdio_exit(void); 278 - void brcmf_sdio_register(void); 278 + int brcmf_sdio_register(void); 279 + #else 280 + static inline void brcmf_sdio_exit(void) { } 281 + static inline int brcmf_sdio_register(void) { return 0; } 279 282 #endif 283 + 280 284 #ifdef CONFIG_BRCMFMAC_USB 281 285 void brcmf_usb_exit(void); 282 - void brcmf_usb_register(void); 286 + int brcmf_usb_register(void); 287 + #else 288 + static inline void brcmf_usb_exit(void) { } 289 + static inline int brcmf_usb_register(void) { return 0; } 290 + #endif 291 + 292 + #ifdef CONFIG_BRCMFMAC_PCIE 293 + void brcmf_pcie_exit(void); 294 + int brcmf_pcie_register(void); 295 + #else 296 + static inline void brcmf_pcie_exit(void) { } 297 + static inline int brcmf_pcie_register(void) { return 0; } 283 298 #endif 284 299 285 300 #endif /* BRCMFMAC_BUS_H */
+18 -24
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
··· 1518 1518 } 1519 1519 } 1520 1520 1521 - static void brcmf_driver_register(struct work_struct *work) 1522 - { 1523 - #ifdef CONFIG_BRCMFMAC_SDIO 1524 - brcmf_sdio_register(); 1525 - #endif 1526 - #ifdef CONFIG_BRCMFMAC_USB 1527 - brcmf_usb_register(); 1528 - #endif 1529 - #ifdef CONFIG_BRCMFMAC_PCIE 1530 - brcmf_pcie_register(); 1531 - #endif 1532 - } 1533 - static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); 1534 - 1535 1521 int __init brcmf_core_init(void) 1536 1522 { 1537 - if (!schedule_work(&brcmf_driver_work)) 1538 - return -EBUSY; 1523 + int err; 1539 1524 1525 + err = brcmf_sdio_register(); 1526 + if (err) 1527 + return err; 1528 + 1529 + err = brcmf_usb_register(); 1530 + if (err) 1531 + goto error_usb_register; 1532 + 1533 + err = brcmf_pcie_register(); 1534 + if (err) 1535 + goto error_pcie_register; 1540 1536 return 0; 1537 + 1538 + error_pcie_register: 1539 + brcmf_usb_exit(); 1540 + error_usb_register: 1541 + brcmf_sdio_exit(); 1542 + return err; 1541 1543 } 1542 1544 1543 1545 void __exit brcmf_core_exit(void) 1544 1546 { 1545 - cancel_work_sync(&brcmf_driver_work); 1546 - 1547 - #ifdef CONFIG_BRCMFMAC_SDIO 1548 1547 brcmf_sdio_exit(); 1549 - #endif 1550 - #ifdef CONFIG_BRCMFMAC_USB 1551 1548 brcmf_usb_exit(); 1552 - #endif 1553 - #ifdef CONFIG_BRCMFMAC_PCIE 1554 1549 brcmf_pcie_exit(); 1555 - #endif 1556 1550 } 1557 1551
+2 -7
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
··· 2140 2140 }; 2141 2141 2142 2142 2143 - void brcmf_pcie_register(void) 2143 + int brcmf_pcie_register(void) 2144 2144 { 2145 - int err; 2146 - 2147 2145 brcmf_dbg(PCIE, "Enter\n"); 2148 - err = pci_register_driver(&brcmf_pciedrvr); 2149 - if (err) 2150 - brcmf_err(NULL, "PCIE driver registration failed, err=%d\n", 2151 - err); 2146 + return pci_register_driver(&brcmf_pciedrvr); 2152 2147 } 2153 2148 2154 2149
-5
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h
··· 11 11 struct brcmf_pciedev_info *devinfo; 12 12 }; 13 13 14 - 15 - void brcmf_pcie_exit(void); 16 - void brcmf_pcie_register(void); 17 - 18 - 19 14 #endif /* BRCMFMAC_PCIE_H */
+2 -2
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
··· 1584 1584 usb_deregister(&brcmf_usbdrvr); 1585 1585 } 1586 1586 1587 - void brcmf_usb_register(void) 1587 + int brcmf_usb_register(void) 1588 1588 { 1589 1589 brcmf_dbg(USB, "Enter\n"); 1590 - usb_register(&brcmf_usbdrvr); 1590 + return usb_register(&brcmf_usbdrvr); 1591 1591 }