320-v5.0-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. - do {
  64. - if (++fwctx->curpos == fwctx->req->n_items) {
  65. - ret = 0;
  66. - goto done;
  67. - }
  68. -
  69. - ret = brcmf_fw_request_next_item(fwctx, false);
  70. - } while (ret == -EAGAIN);
  71. -
  72. - return;
  73. -
  74. -fail:
  75. - brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
  76. - dev_name(fwctx->dev), cur->path);
  77. - brcmf_fw_free_request(fwctx->req);
  78. - fwctx->req = NULL;
  79. -done:
  80. + while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) {
  81. + cur = &fwctx->req->items[fwctx->curpos];
  82. + request_firmware(&fw, cur->path, fwctx->dev);
  83. + ret = brcmf_fw_complete_request(fw, ctx);
  84. + }
  85. +
  86. + if (ret) {
  87. + brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
  88. + dev_name(fwctx->dev), cur->path);
  89. + brcmf_fw_free_request(fwctx->req);
  90. + fwctx->req = NULL;
  91. + }
  92. fwctx->done(fwctx->dev, ret, fwctx->req);
  93. kfree(fwctx);
  94. }
  95. @@ -611,7 +577,9 @@ int brcmf_fw_get_firmwares(struct device
  96. void (*fw_cb)(struct device *dev, int err,
  97. struct brcmf_fw_request *req))
  98. {
  99. + struct brcmf_fw_item *first = &req->items[0];
  100. struct brcmf_fw *fwctx;
  101. + int ret;
  102. brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
  103. if (!fw_cb)
  104. @@ -628,7 +596,12 @@ int brcmf_fw_get_firmwares(struct device
  105. fwctx->req = req;
  106. fwctx->done = fw_cb;
  107. - brcmf_fw_request_next_item(fwctx, true);
  108. + ret = request_firmware_nowait(THIS_MODULE, true, first->path,
  109. + fwctx->dev, GFP_KERNEL, fwctx,
  110. + brcmf_fw_request_done);
  111. + if (ret < 0)
  112. + brcmf_fw_request_done(NULL, fwctx);
  113. +
  114. return 0;
  115. }