libertas: harden-up exit paths
[deliverable/linux.git] / drivers / net / wireless / libertas / firmware.c
CommitLineData
370803c2
DD
1/*
2 * Firmware loading and handling functions.
3 */
4
5#include <linux/firmware.h>
6#include <linux/module.h>
7
8#include "decl.h"
9
10/**
11 * lbs_get_firmware - Retrieves two-stage firmware
12 *
13 * @dev: A pointer to &device structure
14 * @card_model: Bus-specific card model ID used to filter firmware table
15 * elements
16 * @fw_table: Table of firmware file names and device model numbers
17 * terminated by an entry with a NULL helper name
18 * @helper: On success, the helper firmware; caller must free
19 * @mainfw: On success, the main firmware; caller must free
20 *
21 * returns: 0 on success, non-zero on failure
22 */
23int lbs_get_firmware(struct device *dev, u32 card_model,
24 const struct lbs_fw_table *fw_table,
25 const struct firmware **helper,
26 const struct firmware **mainfw)
27{
28 const struct lbs_fw_table *iter;
29 int ret;
30
31 BUG_ON(helper == NULL);
32 BUG_ON(mainfw == NULL);
33
34 /* Search for firmware to use from the table. */
35 iter = fw_table;
36 while (iter && iter->helper) {
37 if (iter->model != card_model)
38 goto next;
39
40 if (*helper == NULL) {
41 ret = request_firmware(helper, iter->helper, dev);
42 if (ret)
43 goto next;
44
45 /* If the device has one-stage firmware (ie cf8305) and
46 * we've got it then we don't need to bother with the
47 * main firmware.
48 */
49 if (iter->fwname == NULL)
50 return 0;
51 }
52
53 if (*mainfw == NULL) {
54 ret = request_firmware(mainfw, iter->fwname, dev);
55 if (ret) {
56 /* Clear the helper to ensure we don't have
57 * mismatched firmware pairs.
58 */
59 release_firmware(*helper);
60 *helper = NULL;
61 }
62 }
63
64 if (*helper && *mainfw)
65 return 0;
66
67 next:
68 iter++;
69 }
70
71 /* Failed */
72 release_firmware(*helper);
73 *helper = NULL;
74 release_firmware(*mainfw);
75 *mainfw = NULL;
76
77 return -ENOENT;
78}
79EXPORT_SYMBOL_GPL(lbs_get_firmware);
This page took 0.027753 seconds and 5 git commands to generate.