aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/firmware.c
diff options
context:
space:
mode:
authorDaniel Drake <dsd@laptop.org>2012-04-16 23:52:42 +0100
committerJohn W. Linville <linville@tuxdriver.com>2012-04-17 14:57:13 -0400
commit370803c25dd77332ee4ca97884c3a5e1e1eafbca (patch)
tree1ed72c00356fe54b913fa4ec26a837c7014eb1e0 /drivers/net/wireless/libertas/firmware.c
parentrt2x00: Don't let mac80211 send a BAR when an AMPDU subframe fails (diff)
downloadlinux-dev-370803c25dd77332ee4ca97884c3a5e1e1eafbca.tar.xz
linux-dev-370803c25dd77332ee4ca97884c3a5e1e1eafbca.zip
libertas: Firmware loading simplifications
Remove the ability to pass module parameters with firmware filenames for USB and SDIO interfaces. Remove the ability to pass custom "user" filenames to lbs_get_firmware(). Remove the ability to reprogram internal device memory with a different firmware from the USB driver (we don't know of any users), and simplify the OLPC firmware loading quirk to simply placing the OLPC firmware at the top of the list (we don't know of any users other than OLPC). Move lbs_get_firmware() into its own file. These simplifications should have no real-life effect but make the upcoming transition to asynchronous firmware loading considerably less painful. Signed-off-by: Daniel Drake <dsd@laptop.org> Acked-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/firmware.c')
-rw-r--r--drivers/net/wireless/libertas/firmware.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/net/wireless/libertas/firmware.c b/drivers/net/wireless/libertas/firmware.c
new file mode 100644
index 000000000000..0c8c845b4901
--- /dev/null
+++ b/drivers/net/wireless/libertas/firmware.c
@@ -0,0 +1,79 @@
+/*
+ * Firmware loading and handling functions.
+ */
+
+#include <linux/firmware.h>
+#include <linux/module.h>
+
+#include "decl.h"
+
+/**
+ * lbs_get_firmware - Retrieves two-stage firmware
+ *
+ * @dev: A pointer to &device structure
+ * @card_model: Bus-specific card model ID used to filter firmware table
+ * elements
+ * @fw_table: Table of firmware file names and device model numbers
+ * terminated by an entry with a NULL helper name
+ * @helper: On success, the helper firmware; caller must free
+ * @mainfw: On success, the main firmware; caller must free
+ *
+ * returns: 0 on success, non-zero on failure
+ */
+int lbs_get_firmware(struct device *dev, u32 card_model,
+ const struct lbs_fw_table *fw_table,
+ const struct firmware **helper,
+ const struct firmware **mainfw)
+{
+ const struct lbs_fw_table *iter;
+ int ret;
+
+ BUG_ON(helper == NULL);
+ BUG_ON(mainfw == NULL);
+
+ /* Search for firmware to use from the table. */
+ iter = fw_table;
+ while (iter && iter->helper) {
+ if (iter->model != card_model)
+ goto next;
+
+ if (*helper == NULL) {
+ ret = request_firmware(helper, iter->helper, dev);
+ if (ret)
+ goto next;
+
+ /* If the device has one-stage firmware (ie cf8305) and
+ * we've got it then we don't need to bother with the
+ * main firmware.
+ */
+ if (iter->fwname == NULL)
+ return 0;
+ }
+
+ if (*mainfw == NULL) {
+ ret = request_firmware(mainfw, iter->fwname, dev);
+ if (ret) {
+ /* Clear the helper to ensure we don't have
+ * mismatched firmware pairs.
+ */
+ release_firmware(*helper);
+ *helper = NULL;
+ }
+ }
+
+ if (*helper && *mainfw)
+ return 0;
+
+ next:
+ iter++;
+ }
+
+ /* Failed */
+ release_firmware(*helper);
+ *helper = NULL;
+ release_firmware(*mainfw);
+ *mainfw = NULL;
+
+ return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(lbs_get_firmware);