2
0

320-v4.21-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. From 5b587496dc63595b71265d986ce69728c2724370 Mon Sep 17 00:00:00 2001
  2. From: Hans de Goede <[email protected]>
  3. Date: Wed, 10 Oct 2018 13:00:59 +0200
  4. Subject: [PATCH] brcmfmac: Remove recursion from firmware load error handling
  5. Before this commit brcmf_fw_request_done would call
  6. brcmf_fw_request_next_item to load the next item, which on an error would
  7. call brcmf_fw_request_done, which if the error is recoverable (*) will
  8. then continue calling brcmf_fw_request_next_item for the next item again
  9. which on an error will call brcmf_fw_request_done again...
  10. This does not blow up because we only have a limited number of items so
  11. we never recurse too deep. But the recursion is still quite ugly and
  12. frankly is giving me a headache, so lets fix this.
  13. This commit fixes this by removing brcmf_fw_request_next_item and by
  14. making brcmf_fw_get_firmwares and brcmf_fw_request_done directly call
  15. firmware_request_nowait resp. firmware_request themselves.
  16. *) brcmf_fw_request_nvram_done fallback path succeeds or
  17. BRCMF_FW_REQF_OPTIONAL is set
  18. Signed-off-by: Hans de Goede <[email protected]>
  19. Signed-off-by: Kalle Valo <[email protected]>
  20. ---
  21. .../broadcom/brcm80211/brcmfmac/firmware.c | 65 +++++++---------------
  22. 1 file changed, 19 insertions(+), 46 deletions(-)
  23. --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
  24. +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
  25. @@ -532,33 +532,6 @@ static int brcmf_fw_complete_request(con
  26. return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
  27. }
  28. -static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
  29. -{
  30. - struct brcmf_fw_item *cur;
  31. - const struct firmware *fw = NULL;
  32. - int ret;
  33. -
  34. - cur = &fwctx->req->items[fwctx->curpos];
  35. -
  36. - brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "",
  37. - cur->path);
  38. -
  39. - if (async)
  40. - ret = request_firmware_nowait(THIS_MODULE, true, cur->path,
  41. - fwctx->dev, GFP_KERNEL, fwctx,
  42. - brcmf_fw_request_done);
  43. - else
  44. - ret = request_firmware(&fw, cur->path, fwctx->dev);
  45. -
  46. - if (ret < 0) {
  47. - brcmf_fw_request_done(NULL, fwctx);
  48. - } else if (!async && fw) {
  49. - brcmf_fw_complete_request(fw, fwctx);
  50. - return -EAGAIN;
  51. - }
  52. - return 0;
  53. -}
  54. -
  55. static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
  56. {
  57. struct brcmf_fw *fwctx = ctx;
  58. @@ -568,26 +541,19 @@ static void brcmf_fw_request_done(const
  59. cur = &fwctx->req->items[fwctx->curpos];
  60. ret = brcmf_fw_complete_request(fw, fwctx);
  61. - if (ret < 0)
  62. - goto fail;
  63. -
  64. - do {
  65. - if (++fwctx->curpos == fwctx->req->n_items) {
  66. - ret = 0;
  67. - goto done;
  68. - }
  69. - ret = brcmf_fw_request_next_item(fwctx, false);
  70. - } while (ret == -EAGAIN);
  71. -
  72. - return;
  73. + while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) {
  74. + cur = &fwctx->req->items[fwctx->curpos];
  75. + request_firmware(&fw, cur->path, fwctx->dev);
  76. + ret = brcmf_fw_complete_request(fw, ctx);
  77. + }
  78. -fail:
  79. - brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
  80. - dev_name(fwctx->dev), cur->path);
  81. - brcmf_fw_free_request(fwctx->req);
  82. - fwctx->req = NULL;
  83. -done:
  84. + if (ret) {
  85. + brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
  86. + dev_name(fwctx->dev), cur->path);
  87. + brcmf_fw_free_request(fwctx->req);
  88. + fwctx->req = NULL;
  89. + }
  90. fwctx->done(fwctx->dev, ret, fwctx->req);
  91. kfree(fwctx);
  92. }
  93. @@ -611,7 +577,9 @@ int brcmf_fw_get_firmwares(struct device
  94. void (*fw_cb)(struct device *dev, int err,
  95. struct brcmf_fw_request *req))
  96. {
  97. + struct brcmf_fw_item *first = &req->items[0];
  98. struct brcmf_fw *fwctx;
  99. + int ret;
  100. brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
  101. if (!fw_cb)
  102. @@ -628,7 +596,12 @@ int brcmf_fw_get_firmwares(struct device
  103. fwctx->req = req;
  104. fwctx->done = fw_cb;
  105. - brcmf_fw_request_next_item(fwctx, true);
  106. + ret = request_firmware_nowait(THIS_MODULE, true, first->path,
  107. + fwctx->dev, GFP_KERNEL, fwctx,
  108. + brcmf_fw_request_done);
  109. + if (ret < 0)
  110. + brcmf_fw_request_done(NULL, fwctx);
  111. +
  112. return 0;
  113. }