0001
0002
0003
0004
0005
0006 #include <linux/sched.h>
0007 #include <linux/firmware.h>
0008 #include <linux/module.h>
0009
0010 #include "dev.h"
0011 #include "decl.h"
0012
0013 static void load_next_firmware_from_table(struct lbs_private *private);
0014
0015 static void lbs_fw_loaded(struct lbs_private *priv, int ret,
0016 const struct firmware *helper, const struct firmware *mainfw)
0017 {
0018 unsigned long flags;
0019
0020 lbs_deb_fw("firmware load complete, code %d\n", ret);
0021
0022
0023 priv->fw_callback(priv, ret, helper, mainfw);
0024
0025 spin_lock_irqsave(&priv->driver_lock, flags);
0026 priv->fw_callback = NULL;
0027 wake_up(&priv->fw_waitq);
0028 spin_unlock_irqrestore(&priv->driver_lock, flags);
0029 }
0030
0031 static void do_load_firmware(struct lbs_private *priv, const char *name,
0032 void (*cb)(const struct firmware *fw, void *context))
0033 {
0034 int ret;
0035
0036 lbs_deb_fw("Requesting %s\n", name);
0037 ret = request_firmware_nowait(THIS_MODULE, true, name,
0038 priv->fw_device, GFP_KERNEL, priv, cb);
0039 if (ret) {
0040 lbs_deb_fw("request_firmware_nowait error %d\n", ret);
0041 lbs_fw_loaded(priv, ret, NULL, NULL);
0042 }
0043 }
0044
0045 static void main_firmware_cb(const struct firmware *firmware, void *context)
0046 {
0047 struct lbs_private *priv = context;
0048
0049 if (!firmware) {
0050
0051 load_next_firmware_from_table(priv);
0052 return;
0053 }
0054
0055
0056 lbs_fw_loaded(priv, 0, priv->helper_fw, firmware);
0057 if (priv->helper_fw) {
0058 release_firmware (priv->helper_fw);
0059 priv->helper_fw = NULL;
0060 }
0061 release_firmware (firmware);
0062 }
0063
0064 static void helper_firmware_cb(const struct firmware *firmware, void *context)
0065 {
0066 struct lbs_private *priv = context;
0067
0068 if (!firmware) {
0069
0070 load_next_firmware_from_table(priv);
0071 return;
0072 }
0073
0074
0075 if (priv->fw_iter->fwname) {
0076 priv->helper_fw = firmware;
0077 do_load_firmware(priv, priv->fw_iter->fwname, main_firmware_cb);
0078 } else {
0079
0080 lbs_fw_loaded(priv, 0, firmware, NULL);
0081 }
0082 }
0083
0084 static void load_next_firmware_from_table(struct lbs_private *priv)
0085 {
0086 const struct lbs_fw_table *iter;
0087
0088 if (!priv->fw_iter)
0089 iter = priv->fw_table;
0090 else
0091 iter = ++priv->fw_iter;
0092
0093 if (priv->helper_fw) {
0094 release_firmware(priv->helper_fw);
0095 priv->helper_fw = NULL;
0096 }
0097
0098 next:
0099 if (!iter->helper) {
0100
0101 lbs_fw_loaded(priv, -ENOENT, NULL, NULL);
0102 return;
0103 }
0104
0105 if (iter->model != priv->fw_model) {
0106 iter++;
0107 goto next;
0108 }
0109
0110 priv->fw_iter = iter;
0111 do_load_firmware(priv, iter->helper, helper_firmware_cb);
0112 }
0113
0114 void lbs_wait_for_firmware_load(struct lbs_private *priv)
0115 {
0116 wait_event(priv->fw_waitq, priv->fw_callback == NULL);
0117 }
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 int lbs_get_firmware_async(struct lbs_private *priv, struct device *device,
0132 u32 card_model, const struct lbs_fw_table *fw_table,
0133 lbs_fw_cb callback)
0134 {
0135 unsigned long flags;
0136
0137 spin_lock_irqsave(&priv->driver_lock, flags);
0138 if (priv->fw_callback) {
0139 lbs_deb_fw("firmware load already in progress\n");
0140 spin_unlock_irqrestore(&priv->driver_lock, flags);
0141 return -EBUSY;
0142 }
0143
0144 priv->fw_device = device;
0145 priv->fw_callback = callback;
0146 priv->fw_table = fw_table;
0147 priv->fw_iter = NULL;
0148 priv->fw_model = card_model;
0149 spin_unlock_irqrestore(&priv->driver_lock, flags);
0150
0151 lbs_deb_fw("Starting async firmware load\n");
0152 load_next_firmware_from_table(priv);
0153 return 0;
0154 }
0155 EXPORT_SYMBOL_GPL(lbs_get_firmware_async);
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172 int lbs_get_firmware(struct device *dev, u32 card_model,
0173 const struct lbs_fw_table *fw_table,
0174 const struct firmware **helper,
0175 const struct firmware **mainfw)
0176 {
0177 const struct lbs_fw_table *iter;
0178 int ret;
0179
0180 BUG_ON(helper == NULL);
0181 BUG_ON(mainfw == NULL);
0182
0183
0184 iter = fw_table;
0185 while (iter && iter->helper) {
0186 if (iter->model != card_model)
0187 goto next;
0188
0189 if (*helper == NULL) {
0190 ret = request_firmware(helper, iter->helper, dev);
0191 if (ret)
0192 goto next;
0193
0194
0195
0196
0197
0198 if (iter->fwname == NULL)
0199 return 0;
0200 }
0201
0202 if (*mainfw == NULL) {
0203 ret = request_firmware(mainfw, iter->fwname, dev);
0204 if (ret) {
0205
0206
0207
0208 release_firmware(*helper);
0209 *helper = NULL;
0210 }
0211 }
0212
0213 if (*helper && *mainfw)
0214 return 0;
0215
0216 next:
0217 iter++;
0218 }
0219
0220
0221 release_firmware(*helper);
0222 *helper = NULL;
0223 release_firmware(*mainfw);
0224 *mainfw = NULL;
0225
0226 return -ENOENT;
0227 }
0228 EXPORT_SYMBOL_GPL(lbs_get_firmware);