1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/firmware.h>
4 #include <linux/module.h>
5 #include <linux/slab.h>
7 #include "sysfs_upload.h"
10 * Support for user-space to initiate a firmware upload to a device.
13 static const char * const fw_upload_prog_str
[] = {
14 [FW_UPLOAD_PROG_IDLE
] = "idle",
15 [FW_UPLOAD_PROG_RECEIVING
] = "receiving",
16 [FW_UPLOAD_PROG_PREPARING
] = "preparing",
17 [FW_UPLOAD_PROG_TRANSFERRING
] = "transferring",
18 [FW_UPLOAD_PROG_PROGRAMMING
] = "programming"
21 static const char * const fw_upload_err_str
[] = {
22 [FW_UPLOAD_ERR_NONE
] = "none",
23 [FW_UPLOAD_ERR_HW_ERROR
] = "hw-error",
24 [FW_UPLOAD_ERR_TIMEOUT
] = "timeout",
25 [FW_UPLOAD_ERR_CANCELED
] = "user-abort",
26 [FW_UPLOAD_ERR_BUSY
] = "device-busy",
27 [FW_UPLOAD_ERR_INVALID_SIZE
] = "invalid-file-size",
28 [FW_UPLOAD_ERR_RW_ERROR
] = "read-write-error",
29 [FW_UPLOAD_ERR_WEAROUT
] = "flash-wearout",
30 [FW_UPLOAD_ERR_FW_INVALID
] = "firmware-invalid",
33 static const char *fw_upload_progress(struct device
*dev
,
34 enum fw_upload_prog prog
)
36 const char *status
= "unknown-status";
38 if (prog
< FW_UPLOAD_PROG_MAX
)
39 status
= fw_upload_prog_str
[prog
];
41 dev_err(dev
, "Invalid status during secure update: %d\n", prog
);
46 static const char *fw_upload_error(struct device
*dev
,
47 enum fw_upload_err err_code
)
49 const char *error
= "unknown-error";
51 if (err_code
< FW_UPLOAD_ERR_MAX
)
52 error
= fw_upload_err_str
[err_code
];
54 dev_err(dev
, "Invalid error code during secure update: %d\n",
61 status_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
63 struct fw_upload_priv
*fwlp
= to_fw_sysfs(dev
)->fw_upload_priv
;
65 return sysfs_emit(buf
, "%s\n", fw_upload_progress(dev
, fwlp
->progress
));
67 DEVICE_ATTR_RO(status
);
70 error_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
72 struct fw_upload_priv
*fwlp
= to_fw_sysfs(dev
)->fw_upload_priv
;
75 mutex_lock(&fwlp
->lock
);
77 if (fwlp
->progress
!= FW_UPLOAD_PROG_IDLE
)
79 else if (!fwlp
->err_code
)
82 ret
= sysfs_emit(buf
, "%s:%s\n",
83 fw_upload_progress(dev
, fwlp
->err_progress
),
84 fw_upload_error(dev
, fwlp
->err_code
));
86 mutex_unlock(&fwlp
->lock
);
90 DEVICE_ATTR_RO(error
);
92 static ssize_t
cancel_store(struct device
*dev
, struct device_attribute
*attr
,
93 const char *buf
, size_t count
)
95 struct fw_upload_priv
*fwlp
= to_fw_sysfs(dev
)->fw_upload_priv
;
99 if (kstrtobool(buf
, &cancel
) || !cancel
)
102 mutex_lock(&fwlp
->lock
);
103 if (fwlp
->progress
== FW_UPLOAD_PROG_IDLE
)
106 fwlp
->ops
->cancel(fwlp
->fw_upload
);
107 mutex_unlock(&fwlp
->lock
);
111 DEVICE_ATTR_WO(cancel
);
113 static ssize_t
remaining_size_show(struct device
*dev
,
114 struct device_attribute
*attr
, char *buf
)
116 struct fw_upload_priv
*fwlp
= to_fw_sysfs(dev
)->fw_upload_priv
;
118 return sysfs_emit(buf
, "%u\n", fwlp
->remaining_size
);
120 DEVICE_ATTR_RO(remaining_size
);
123 fw_upload_is_visible(struct kobject
*kobj
, struct attribute
*attr
, int n
)
125 static struct fw_sysfs
*fw_sysfs
;
127 fw_sysfs
= to_fw_sysfs(kobj_to_dev(kobj
));
129 if (fw_sysfs
->fw_upload_priv
|| attr
== &dev_attr_loading
.attr
)
135 static void fw_upload_update_progress(struct fw_upload_priv
*fwlp
,
136 enum fw_upload_prog new_progress
)
138 mutex_lock(&fwlp
->lock
);
139 fwlp
->progress
= new_progress
;
140 mutex_unlock(&fwlp
->lock
);
143 static void fw_upload_set_error(struct fw_upload_priv
*fwlp
,
144 enum fw_upload_err err_code
)
146 mutex_lock(&fwlp
->lock
);
147 fwlp
->err_progress
= fwlp
->progress
;
148 fwlp
->err_code
= err_code
;
149 mutex_unlock(&fwlp
->lock
);
152 static void fw_upload_prog_complete(struct fw_upload_priv
*fwlp
)
154 mutex_lock(&fwlp
->lock
);
155 fwlp
->progress
= FW_UPLOAD_PROG_IDLE
;
156 mutex_unlock(&fwlp
->lock
);
159 static void fw_upload_main(struct work_struct
*work
)
161 struct fw_upload_priv
*fwlp
;
162 struct fw_sysfs
*fw_sysfs
;
163 u32 written
= 0, offset
= 0;
164 enum fw_upload_err ret
;
165 struct device
*fw_dev
;
166 struct fw_upload
*fwl
;
168 fwlp
= container_of(work
, struct fw_upload_priv
, work
);
169 fwl
= fwlp
->fw_upload
;
170 fw_sysfs
= (struct fw_sysfs
*)fwl
->priv
;
171 fw_dev
= &fw_sysfs
->dev
;
173 fw_upload_update_progress(fwlp
, FW_UPLOAD_PROG_PREPARING
);
174 ret
= fwlp
->ops
->prepare(fwl
, fwlp
->data
, fwlp
->remaining_size
);
175 if (ret
!= FW_UPLOAD_ERR_NONE
) {
176 fw_upload_set_error(fwlp
, ret
);
180 fw_upload_update_progress(fwlp
, FW_UPLOAD_PROG_TRANSFERRING
);
181 while (fwlp
->remaining_size
) {
182 ret
= fwlp
->ops
->write(fwl
, fwlp
->data
, offset
,
183 fwlp
->remaining_size
, &written
);
184 if (ret
!= FW_UPLOAD_ERR_NONE
|| !written
) {
185 if (ret
== FW_UPLOAD_ERR_NONE
) {
186 dev_warn(fw_dev
, "write-op wrote zero data\n");
187 ret
= FW_UPLOAD_ERR_RW_ERROR
;
189 fw_upload_set_error(fwlp
, ret
);
193 fwlp
->remaining_size
-= written
;
197 fw_upload_update_progress(fwlp
, FW_UPLOAD_PROG_PROGRAMMING
);
198 ret
= fwlp
->ops
->poll_complete(fwl
);
199 if (ret
!= FW_UPLOAD_ERR_NONE
)
200 fw_upload_set_error(fwlp
, ret
);
203 if (fwlp
->ops
->cleanup
)
204 fwlp
->ops
->cleanup(fwl
);
207 put_device(fw_dev
->parent
);
210 * Note: fwlp->remaining_size is left unmodified here to provide
211 * additional information on errors. It will be reinitialized when
212 * the next firmeware upload begins.
214 mutex_lock(&fw_lock
);
215 fw_free_paged_buf(fw_sysfs
->fw_priv
);
216 fw_state_init(fw_sysfs
->fw_priv
);
217 mutex_unlock(&fw_lock
);
219 fw_upload_prog_complete(fwlp
);
223 * Start a worker thread to upload data to the parent driver.
224 * Must be called with fw_lock held.
226 int fw_upload_start(struct fw_sysfs
*fw_sysfs
)
228 struct fw_priv
*fw_priv
= fw_sysfs
->fw_priv
;
229 struct device
*fw_dev
= &fw_sysfs
->dev
;
230 struct fw_upload_priv
*fwlp
;
232 if (!fw_sysfs
->fw_upload_priv
)
235 if (!fw_priv
->size
) {
236 fw_free_paged_buf(fw_priv
);
237 fw_state_init(fw_sysfs
->fw_priv
);
241 fwlp
= fw_sysfs
->fw_upload_priv
;
242 mutex_lock(&fwlp
->lock
);
244 /* Do not interfere with an on-going fw_upload */
245 if (fwlp
->progress
!= FW_UPLOAD_PROG_IDLE
) {
246 mutex_unlock(&fwlp
->lock
);
250 get_device(fw_dev
->parent
); /* released in fw_upload_main */
252 fwlp
->progress
= FW_UPLOAD_PROG_RECEIVING
;
254 fwlp
->remaining_size
= fw_priv
->size
;
255 fwlp
->data
= fw_priv
->data
;
257 pr_debug("%s: fw-%s fw_priv=%p data=%p size=%u\n",
258 __func__
, fw_priv
->fw_name
,
259 fw_priv
, fw_priv
->data
,
260 (unsigned int)fw_priv
->size
);
262 queue_work(system_long_wq
, &fwlp
->work
);
263 mutex_unlock(&fwlp
->lock
);
268 void fw_upload_free(struct fw_sysfs
*fw_sysfs
)
270 struct fw_upload_priv
*fw_upload_priv
= fw_sysfs
->fw_upload_priv
;
272 free_fw_priv(fw_sysfs
->fw_priv
);
273 kfree(fw_upload_priv
->fw_upload
);
274 kfree(fw_upload_priv
);
278 * firmware_upload_register() - register for the firmware upload sysfs API
279 * @module: kernel module of this device
280 * @parent: parent device instantiating firmware upload
281 * @name: firmware name to be associated with this device
282 * @ops: pointer to structure of firmware upload ops
283 * @dd_handle: pointer to parent driver private data
285 * @name must be unique among all users of firmware upload. The firmware
286 * sysfs files for this device will be found at /sys/class/firmware/@name.
288 * Return: struct fw_upload pointer or ERR_PTR()
292 firmware_upload_register(struct module
*module
, struct device
*parent
,
293 const char *name
, const struct fw_upload_ops
*ops
,
296 u32 opt_flags
= FW_OPT_NOCACHE
;
297 struct fw_upload
*fw_upload
;
298 struct fw_upload_priv
*fw_upload_priv
;
299 struct fw_sysfs
*fw_sysfs
;
300 struct fw_priv
*fw_priv
;
301 struct device
*fw_dev
;
304 if (!name
|| name
[0] == '\0')
305 return ERR_PTR(-EINVAL
);
307 if (!ops
|| !ops
->cancel
|| !ops
->prepare
||
308 !ops
->write
|| !ops
->poll_complete
) {
309 dev_err(parent
, "Attempt to register without all required ops\n");
310 return ERR_PTR(-EINVAL
);
313 if (!try_module_get(module
))
314 return ERR_PTR(-EFAULT
);
316 fw_upload
= kzalloc(sizeof(*fw_upload
), GFP_KERNEL
);
319 goto exit_module_put
;
322 fw_upload_priv
= kzalloc(sizeof(*fw_upload_priv
), GFP_KERNEL
);
323 if (!fw_upload_priv
) {
328 fw_upload_priv
->fw_upload
= fw_upload
;
329 fw_upload_priv
->ops
= ops
;
330 mutex_init(&fw_upload_priv
->lock
);
331 fw_upload_priv
->module
= module
;
332 fw_upload_priv
->name
= name
;
333 fw_upload_priv
->err_code
= 0;
334 fw_upload_priv
->progress
= FW_UPLOAD_PROG_IDLE
;
335 INIT_WORK(&fw_upload_priv
->work
, fw_upload_main
);
336 fw_upload
->dd_handle
= dd_handle
;
338 fw_sysfs
= fw_create_instance(NULL
, name
, parent
, opt_flags
);
339 if (IS_ERR(fw_sysfs
)) {
340 ret
= PTR_ERR(fw_sysfs
);
341 goto free_fw_upload_priv
;
343 fw_upload
->priv
= fw_sysfs
;
344 fw_sysfs
->fw_upload_priv
= fw_upload_priv
;
345 fw_dev
= &fw_sysfs
->dev
;
347 ret
= alloc_lookup_fw_priv(name
, &fw_cache
, &fw_priv
, NULL
, 0, 0,
354 fw_priv
->is_paged_buf
= true;
355 fw_sysfs
->fw_priv
= fw_priv
;
357 ret
= device_add(fw_dev
);
359 dev_err(fw_dev
, "%s: device_register failed\n", __func__
);
361 goto exit_module_put
;
370 kfree(fw_upload_priv
);
380 EXPORT_SYMBOL_GPL(firmware_upload_register
);
383 * firmware_upload_unregister() - Unregister firmware upload interface
384 * @fw_upload: pointer to struct fw_upload
386 void firmware_upload_unregister(struct fw_upload
*fw_upload
)
388 struct fw_sysfs
*fw_sysfs
= fw_upload
->priv
;
389 struct fw_upload_priv
*fw_upload_priv
= fw_sysfs
->fw_upload_priv
;
390 struct module
*module
= fw_upload_priv
->module
;
392 mutex_lock(&fw_upload_priv
->lock
);
393 if (fw_upload_priv
->progress
== FW_UPLOAD_PROG_IDLE
) {
394 mutex_unlock(&fw_upload_priv
->lock
);
398 fw_upload_priv
->ops
->cancel(fw_upload
);
399 mutex_unlock(&fw_upload_priv
->lock
);
401 /* Ensure lower-level device-driver is finished */
402 flush_work(&fw_upload_priv
->work
);
405 device_unregister(&fw_sysfs
->dev
);
408 EXPORT_SYMBOL_GPL(firmware_upload_unregister
);