123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- From d09ae51a4b676151edaf572bcd5f272b5532639f Mon Sep 17 00:00:00 2001
- From: Arend Van Spriel <[email protected]>
- Date: Thu, 22 Mar 2018 21:28:26 +0100
- Subject: [PATCH] brcmfmac: pass struct in brcmf_fw_get_firmwares()
- Make the function brcmf_fw_get_firmwares() a bit more easy to extend
- using a structure to pass the request parameters.
- Reviewed-by: Hante Meuleman <[email protected]>
- Reviewed-by: Pieter-Paul Giesberts <[email protected]>
- Reviewed-by: Franky Lin <[email protected]>
- Signed-off-by: Arend van Spriel <[email protected]>
- Signed-off-by: Kalle Valo <[email protected]>
- ---
- .../broadcom/brcm80211/brcmfmac/firmware.c | 175 ++++++++++++++-------
- .../broadcom/brcm80211/brcmfmac/firmware.h | 43 +++--
- .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 38 ++++-
- .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 32 +++-
- .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 43 ++++-
- 5 files changed, 245 insertions(+), 86 deletions(-)
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
- @@ -438,18 +438,31 @@ void brcmf_fw_nvram_free(void *nvram)
-
- struct brcmf_fw {
- struct device *dev;
- - u16 flags;
- - const struct firmware *code;
- - const char *nvram_name;
- - u16 domain_nr;
- - u16 bus_nr;
- - void (*done)(struct device *dev, int err, const struct firmware *fw,
- - void *nvram_image, u32 nvram_len);
- + struct brcmf_fw_request *req;
- + u32 curpos;
- + void (*done)(struct device *dev, int err, struct brcmf_fw_request *req);
- };
-
- +static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
- +
- +static void brcmf_fw_free_request(struct brcmf_fw_request *req)
- +{
- + struct brcmf_fw_item *item;
- + int i;
- +
- + for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) {
- + if (item->type == BRCMF_FW_TYPE_BINARY)
- + release_firmware(item->binary);
- + else if (item->type == BRCMF_FW_TYPE_NVRAM)
- + brcmf_fw_nvram_free(item->nv_data.data);
- + }
- + kfree(req);
- +}
- +
- static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
- {
- struct brcmf_fw *fwctx = ctx;
- + struct brcmf_fw_item *cur;
- u32 nvram_length = 0;
- void *nvram = NULL;
- u8 *data = NULL;
- @@ -457,83 +470,150 @@ static void brcmf_fw_request_nvram_done(
- bool raw_nvram;
-
- brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
- +
- + cur = &fwctx->req->items[fwctx->curpos];
- +
- if (fw && fw->data) {
- data = (u8 *)fw->data;
- data_len = fw->size;
- raw_nvram = false;
- } else {
- data = bcm47xx_nvram_get_contents(&data_len);
- - if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
- + if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
- goto fail;
- raw_nvram = true;
- }
-
- if (data)
- nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
- - fwctx->domain_nr, fwctx->bus_nr);
- + fwctx->req->domain_nr,
- + fwctx->req->bus_nr);
-
- if (raw_nvram)
- bcm47xx_nvram_release_contents(data);
- release_firmware(fw);
- - if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
- + if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
- goto fail;
-
- - fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length);
- - kfree(fwctx);
- + brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
- + cur->nv_data.data = nvram;
- + cur->nv_data.len = nvram_length;
- return;
-
- fail:
- brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
- - release_firmware(fwctx->code);
- - fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0);
- + fwctx->done(fwctx->dev, -ENOENT, NULL);
- + brcmf_fw_free_request(fwctx->req);
- kfree(fwctx);
- }
-
- -static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
- +static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
- +{
- + struct brcmf_fw_item *cur;
- + const struct firmware *fw = NULL;
- + int ret;
- +
- + cur = &fwctx->req->items[fwctx->curpos];
- +
- + brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "",
- + cur->path);
- +
- + if (async)
- + ret = request_firmware_nowait(THIS_MODULE, true, cur->path,
- + fwctx->dev, GFP_KERNEL, fwctx,
- + brcmf_fw_request_done);
- + else
- + ret = request_firmware(&fw, cur->path, fwctx->dev);
- +
- + if (ret < 0) {
- + brcmf_fw_request_done(NULL, fwctx);
- + } else if (!async && fw) {
- + brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path,
- + fw ? "" : "not ");
- + if (cur->type == BRCMF_FW_TYPE_BINARY)
- + cur->binary = fw;
- + else if (cur->type == BRCMF_FW_TYPE_NVRAM)
- + brcmf_fw_request_nvram_done(fw, fwctx);
- + else
- + release_firmware(fw);
- +
- + return -EAGAIN;
- + }
- + return 0;
- +}
- +
- +static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
- {
- struct brcmf_fw *fwctx = ctx;
- + struct brcmf_fw_item *cur;
- int ret = 0;
-
- - brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
- - if (!fw) {
- + cur = &fwctx->req->items[fwctx->curpos];
- +
- + brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
- + fw ? "" : "not ");
- +
- + if (fw) {
- + if (cur->type == BRCMF_FW_TYPE_BINARY)
- + cur->binary = fw;
- + else if (cur->type == BRCMF_FW_TYPE_NVRAM)
- + brcmf_fw_request_nvram_done(fw, fwctx);
- + else
- + release_firmware(fw);
- + } else if (cur->type == BRCMF_FW_TYPE_NVRAM) {
- + brcmf_fw_request_nvram_done(NULL, fwctx);
- + } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) {
- ret = -ENOENT;
- goto fail;
- }
- - /* only requested code so done here */
- - if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM))
- - goto done;
- -
- - fwctx->code = fw;
- - ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
- - fwctx->dev, GFP_KERNEL, fwctx,
- - brcmf_fw_request_nvram_done);
-
- - /* pass NULL to nvram callback for bcm47xx fallback */
- - if (ret)
- - brcmf_fw_request_nvram_done(NULL, fwctx);
- + do {
- + if (++fwctx->curpos == fwctx->req->n_items) {
- + ret = 0;
- + goto done;
- + }
- +
- + ret = brcmf_fw_request_next_item(fwctx, false);
- + } while (ret == -EAGAIN);
- +
- return;
-
- fail:
- - brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
- + brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
- + dev_name(fwctx->dev), cur->path);
- + brcmf_fw_free_request(fwctx->req);
- + fwctx->req = NULL;
- done:
- - fwctx->done(fwctx->dev, ret, fw, NULL, 0);
- + fwctx->done(fwctx->dev, ret, fwctx->req);
- kfree(fwctx);
- }
-
- -int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
- - const char *code, const char *nvram,
- - void (*fw_cb)(struct device *dev, int err,
- - const struct firmware *fw,
- - void *nvram_image, u32 nvram_len),
- - u16 domain_nr, u16 bus_nr)
- +static bool brcmf_fw_request_is_valid(struct brcmf_fw_request *req)
- +{
- + struct brcmf_fw_item *item;
- + int i;
- +
- + if (!req->n_items)
- + return false;
- +
- + for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) {
- + if (!item->path)
- + return false;
- + }
- + return true;
- +}
- +
- +int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
- + void (*fw_cb)(struct device *dev, int err,
- + struct brcmf_fw_request *req))
- {
- struct brcmf_fw *fwctx;
-
- brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
- - if (!fw_cb || !code)
- + if (!fw_cb)
- return -EINVAL;
-
- - if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram)
- + if (!brcmf_fw_request_is_valid(req))
- return -EINVAL;
-
- fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL);
- @@ -541,26 +621,11 @@ int brcmf_fw_get_firmwares_pcie(struct d
- return -ENOMEM;
-
- fwctx->dev = dev;
- - fwctx->flags = flags;
- + fwctx->req = req;
- fwctx->done = fw_cb;
- - if (flags & BRCMF_FW_REQUEST_NVRAM)
- - fwctx->nvram_name = nvram;
- - fwctx->domain_nr = domain_nr;
- - fwctx->bus_nr = bus_nr;
- -
- - return request_firmware_nowait(THIS_MODULE, true, code, dev,
- - GFP_KERNEL, fwctx,
- - brcmf_fw_request_code_done);
- -}
-
- -int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
- - const char *code, const char *nvram,
- - void (*fw_cb)(struct device *dev, int err,
- - const struct firmware *fw,
- - void *nvram_image, u32 nvram_len))
- -{
- - return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0,
- - 0);
- + brcmf_fw_request_next_item(fwctx, true);
- + return 0;
- }
-
- static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN],
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
- @@ -16,10 +16,7 @@
- #ifndef BRCMFMAC_FIRMWARE_H
- #define BRCMFMAC_FIRMWARE_H
-
- -#define BRCMF_FW_REQUEST 0x000F
- -#define BRCMF_FW_REQUEST_NVRAM 0x0001
- -#define BRCMF_FW_REQ_FLAGS 0x00F0
- -#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
- +#define BRCMF_FW_REQF_OPTIONAL 0x0001
-
- #define BRCMF_FW_NAME_LEN 320
-
- @@ -54,21 +51,39 @@ int brcmf_fw_map_chip_to_name(u32 chip,
- u32 table_size, char fw_name[BRCMF_FW_NAME_LEN],
- char nvram_name[BRCMF_FW_NAME_LEN]);
- void brcmf_fw_nvram_free(void *nvram);
- +
- +enum brcmf_fw_type {
- + BRCMF_FW_TYPE_BINARY,
- + BRCMF_FW_TYPE_NVRAM
- +};
- +
- +struct brcmf_fw_item {
- + const char *path;
- + enum brcmf_fw_type type;
- + u16 flags;
- + union {
- + const struct firmware *binary;
- + struct {
- + void *data;
- + u32 len;
- + } nv_data;
- + };
- +};
- +
- +struct brcmf_fw_request {
- + u16 domain_nr;
- + u16 bus_nr;
- + u32 n_items;
- + struct brcmf_fw_item items[0];
- +};
- +
- /*
- * Request firmware(s) asynchronously. When the asynchronous request
- * fails it will not use the callback, but call device_release_driver()
- * instead which will call the driver .remove() callback.
- */
- -int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
- - const char *code, const char *nvram,
- - void (*fw_cb)(struct device *dev, int err,
- - const struct firmware *fw,
- - void *nvram_image, u32 nvram_len),
- - u16 domain_nr, u16 bus_nr);
- -int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
- - const char *code, const char *nvram,
- +int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
- void (*fw_cb)(struct device *dev, int err,
- - const struct firmware *fw,
- - void *nvram_image, u32 nvram_len));
- + struct brcmf_fw_request *req));
-
- #endif /* BRCMFMAC_FIRMWARE_H */
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
- @@ -1651,15 +1651,19 @@ static const struct brcmf_buscore_ops br
- .write32 = brcmf_pcie_buscore_write32,
- };
-
- +#define BRCMF_PCIE_FW_CODE 0
- +#define BRCMF_PCIE_FW_NVRAM 1
- +
- static void brcmf_pcie_setup(struct device *dev, int ret,
- - const struct firmware *fw,
- - void *nvram, u32 nvram_len)
- + struct brcmf_fw_request *fwreq)
- {
- + const struct firmware *fw;
- + void *nvram;
- struct brcmf_bus *bus;
- struct brcmf_pciedev *pcie_bus_dev;
- struct brcmf_pciedev_info *devinfo;
- struct brcmf_commonring **flowrings;
- - u32 i;
- + u32 i, nvram_len;
-
- /* check firmware loading result */
- if (ret)
- @@ -1670,6 +1674,11 @@ static void brcmf_pcie_setup(struct devi
- devinfo = pcie_bus_dev->devinfo;
- brcmf_pcie_attach(devinfo);
-
- + fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary;
- + nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data;
- + nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len;
- + kfree(fwreq);
- +
- /* Some of the firmwares have the size of the memory of the device
- * defined inside the firmware. This is because part of the memory in
- * the device is shared and the devision is determined by FW. Parse
- @@ -1730,6 +1739,7 @@ static int
- brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
- {
- int ret;
- + struct brcmf_fw_request *fwreq;
- struct brcmf_pciedev_info *devinfo;
- struct brcmf_pciedev *pcie_bus_dev;
- struct brcmf_bus *bus;
- @@ -1800,12 +1810,26 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
- if (ret)
- goto fail_bus;
-
- - ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM |
- - BRCMF_FW_REQ_NV_OPTIONAL,
- - devinfo->fw_name, devinfo->nvram_name,
- - brcmf_pcie_setup, domain_nr, bus_nr);
- + fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item),
- + GFP_KERNEL);
- + if (!fwreq) {
- + ret = -ENOMEM;
- + goto fail_bus;
- + }
- +
- + fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name;
- + fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
- + fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name;
- + fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
- + fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
- + fwreq->n_items = 2;
- + fwreq->domain_nr = domain_nr;
- + fwreq->bus_nr = bus_nr;
- + ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup);
- if (ret == 0)
- return 0;
- +
- + kfree(fwreq);
- fail_bus:
- kfree(bus->msgbuf);
- kfree(bus);
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
- @@ -4031,14 +4031,19 @@ static const struct brcmf_bus_ops brcmf_
- .get_fwname = brcmf_sdio_get_fwname,
- };
-
- +#define BRCMF_SDIO_FW_CODE 0
- +#define BRCMF_SDIO_FW_NVRAM 1
- +
- static void brcmf_sdio_firmware_callback(struct device *dev, int err,
- - const struct firmware *code,
- - void *nvram, u32 nvram_len)
- + struct brcmf_fw_request *fwreq)
- {
- struct brcmf_bus *bus_if = dev_get_drvdata(dev);
- struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio;
- struct brcmf_sdio *bus = sdiod->bus;
- struct brcmf_core *core = bus->sdio_core;
- + const struct firmware *code;
- + void *nvram;
- + u32 nvram_len;
- u8 saveclk;
-
- brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
- @@ -4046,6 +4051,11 @@ static void brcmf_sdio_firmware_callback
- if (err)
- goto fail;
-
- + code = fwreq->items[BRCMF_SDIO_FW_CODE].binary;
- + nvram = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.data;
- + nvram_len = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.len;
- + kfree(fwreq);
- +
- /* try to download image and nvram to the dongle */
- bus->alp_only = true;
- err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
- @@ -4150,6 +4160,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
- int ret;
- struct brcmf_sdio *bus;
- struct workqueue_struct *wq;
- + struct brcmf_fw_request *fwreq;
-
- brcmf_dbg(TRACE, "Enter\n");
-
- @@ -4240,11 +4251,24 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
- if (ret)
- goto fail;
-
- - ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
- - sdiodev->fw_name, sdiodev->nvram_name,
- + fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item),
- + GFP_KERNEL);
- + if (!fwreq) {
- + ret = -ENOMEM;
- + goto fail;
- + }
- +
- + fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name;
- + fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
- + fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name;
- + fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
- + fwreq->n_items = 2;
- +
- + ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq,
- brcmf_sdio_firmware_callback);
- if (ret != 0) {
- brcmf_err("async firmware request failed: %d\n", ret);
- + kfree(fwreq);
- goto fail;
- }
-
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
- @@ -1155,18 +1155,23 @@ static const struct brcmf_bus_ops brcmf_
- .get_fwname = brcmf_usb_get_fwname,
- };
-
- +#define BRCMF_USB_FW_CODE 0
- +
- static void brcmf_usb_probe_phase2(struct device *dev, int ret,
- - const struct firmware *fw,
- - void *nvram, u32 nvlen)
- + struct brcmf_fw_request *fwreq)
- {
- struct brcmf_bus *bus = dev_get_drvdata(dev);
- struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo;
- + const struct firmware *fw;
-
- if (ret)
- goto error;
-
- brcmf_dbg(USB, "Start fw downloading\n");
-
- + fw = fwreq->items[BRCMF_USB_FW_CODE].binary;
- + kfree(fwreq);
- +
- ret = check_file(fw->data);
- if (ret < 0) {
- brcmf_err("invalid firmware\n");
- @@ -1200,6 +1205,7 @@ static int brcmf_usb_probe_cb(struct brc
- struct brcmf_bus *bus = NULL;
- struct brcmf_usbdev *bus_pub = NULL;
- struct device *dev = devinfo->dev;
- + struct brcmf_fw_request *fwreq;
- int ret;
-
- brcmf_dbg(USB, "Enter\n");
- @@ -1250,11 +1256,22 @@ static int brcmf_usb_probe_cb(struct brc
- if (ret)
- goto fail;
-
- + fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
- + GFP_KERNEL);
- + if (!fwreq) {
- + ret = -ENOMEM;
- + goto fail;
- + }
- +
- + fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
- + fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
- + fwreq->n_items = 1;
- +
- /* request firmware here */
- - ret = brcmf_fw_get_firmwares(dev, 0, devinfo->fw_name, NULL,
- - brcmf_usb_probe_phase2);
- + ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);
- if (ret) {
- brcmf_err("firmware request failed: %d\n", ret);
- + kfree(fwreq);
- goto fail;
- }
-
- @@ -1447,11 +1464,25 @@ static int brcmf_usb_reset_resume(struct
- {
- struct usb_device *usb = interface_to_usbdev(intf);
- struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
- + struct brcmf_fw_request *fwreq;
- + int ret;
-
- brcmf_dbg(USB, "Enter\n");
-
- - return brcmf_fw_get_firmwares(&usb->dev, 0, devinfo->fw_name, NULL,
- - brcmf_usb_probe_phase2);
- + fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
- + GFP_KERNEL);
- + if (!fwreq)
- + return -ENOMEM;
- +
- + fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
- + fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
- + fwreq->n_items = 1;
- +
- + ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2);
- + if (ret < 0)
- + kfree(fwreq);
- +
- + return ret;
- }
-
- #define BRCMF_USB_DEVICE(dev_id) \
|