Commit | Line | Data |
---|---|---|
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 | */ | |
23 | int 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 | } | |
79 | EXPORT_SYMBOL_GPL(lbs_get_firmware); |