PageRenderTime 61ms CodeModel.GetById 18ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/base/firmware_class.c

https://bitbucket.org/evzijst/gittest
C | 583 lines | 424 code | 75 blank | 84 comment | 32 complexity | 1cb2d1d18a72cb07c8619206e0a23f24 MD5 | raw file
  1/*
  2 * firmware_class.c - Multi purpose firmware loading support
  3 *
  4 * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
  5 *
  6 * Please see Documentation/firmware_class/ for more information.
  7 *
  8 */
  9
 10#include <linux/device.h>
 11#include <linux/module.h>
 12#include <linux/init.h>
 13#include <linux/timer.h>
 14#include <linux/vmalloc.h>
 15#include <linux/interrupt.h>
 16#include <linux/bitops.h>
 17#include <asm/semaphore.h>
 18
 19#include <linux/firmware.h>
 20#include "base.h"
 21
 22MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
 23MODULE_DESCRIPTION("Multi purpose firmware loading support");
 24MODULE_LICENSE("GPL");
 25
 26enum {
 27	FW_STATUS_LOADING,
 28	FW_STATUS_DONE,
 29	FW_STATUS_ABORT,
 30	FW_STATUS_READY,
 31};
 32
 33static int loading_timeout = 10;	/* In seconds */
 34
 35/* fw_lock could be moved to 'struct firmware_priv' but since it is just
 36 * guarding for corner cases a global lock should be OK */
 37static DECLARE_MUTEX(fw_lock);
 38
 39struct firmware_priv {
 40	char fw_id[FIRMWARE_NAME_MAX];
 41	struct completion completion;
 42	struct bin_attribute attr_data;
 43	struct firmware *fw;
 44	unsigned long status;
 45	int alloc_size;
 46	struct timer_list timeout;
 47};
 48
 49static inline void
 50fw_load_abort(struct firmware_priv *fw_priv)
 51{
 52	set_bit(FW_STATUS_ABORT, &fw_priv->status);
 53	wmb();
 54	complete(&fw_priv->completion);
 55}
 56
 57static ssize_t
 58firmware_timeout_show(struct class *class, char *buf)
 59{
 60	return sprintf(buf, "%d\n", loading_timeout);
 61}
 62
 63/**
 64 * firmware_timeout_store:
 65 * Description:
 66 *	Sets the number of seconds to wait for the firmware.  Once
 67 *	this expires an error will be return to the driver and no
 68 *	firmware will be provided.
 69 *
 70 *	Note: zero means 'wait for ever'
 71 *
 72 **/
 73static ssize_t
 74firmware_timeout_store(struct class *class, const char *buf, size_t count)
 75{
 76	loading_timeout = simple_strtol(buf, NULL, 10);
 77	return count;
 78}
 79
 80static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
 81
 82static void  fw_class_dev_release(struct class_device *class_dev);
 83int firmware_class_hotplug(struct class_device *dev, char **envp,
 84			   int num_envp, char *buffer, int buffer_size);
 85
 86static struct class firmware_class = {
 87	.name		= "firmware",
 88	.hotplug	= firmware_class_hotplug,
 89	.release	= fw_class_dev_release,
 90};
 91
 92int
 93firmware_class_hotplug(struct class_device *class_dev, char **envp,
 94		       int num_envp, char *buffer, int buffer_size)
 95{
 96	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
 97	int i = 0, len = 0;
 98
 99	if (!test_bit(FW_STATUS_READY, &fw_priv->status))
100		return -ENODEV;
101
102	if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
103			"FIRMWARE=%s", fw_priv->fw_id))
104		return -ENOMEM;
105
106	envp[i] = NULL;
107
108	return 0;
109}
110
111static ssize_t
112firmware_loading_show(struct class_device *class_dev, char *buf)
113{
114	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
115	int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status);
116	return sprintf(buf, "%d\n", loading);
117}
118
119/**
120 * firmware_loading_store: - loading control file
121 * Description:
122 *	The relevant values are:
123 *
124 *	 1: Start a load, discarding any previous partial load.
125 *	 0: Conclude the load and handle the data to the driver code.
126 *	-1: Conclude the load with an error and discard any written data.
127 **/
128static ssize_t
129firmware_loading_store(struct class_device *class_dev,
130		       const char *buf, size_t count)
131{
132	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
133	int loading = simple_strtol(buf, NULL, 10);
134
135	switch (loading) {
136	case 1:
137		down(&fw_lock);
138		vfree(fw_priv->fw->data);
139		fw_priv->fw->data = NULL;
140		fw_priv->fw->size = 0;
141		fw_priv->alloc_size = 0;
142		set_bit(FW_STATUS_LOADING, &fw_priv->status);
143		up(&fw_lock);
144		break;
145	case 0:
146		if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
147			complete(&fw_priv->completion);
148			clear_bit(FW_STATUS_LOADING, &fw_priv->status);
149			break;
150		}
151		/* fallthrough */
152	default:
153		printk(KERN_ERR "%s: unexpected value (%d)\n", __FUNCTION__,
154		       loading);
155		/* fallthrough */
156	case -1:
157		fw_load_abort(fw_priv);
158		break;
159	}
160
161	return count;
162}
163
164static CLASS_DEVICE_ATTR(loading, 0644,
165			firmware_loading_show, firmware_loading_store);
166
167static ssize_t
168firmware_data_read(struct kobject *kobj,
169		   char *buffer, loff_t offset, size_t count)
170{
171	struct class_device *class_dev = to_class_dev(kobj);
172	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
173	struct firmware *fw;
174	ssize_t ret_count = count;
175
176	down(&fw_lock);
177	fw = fw_priv->fw;
178	if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
179		ret_count = -ENODEV;
180		goto out;
181	}
182	if (offset > fw->size) {
183		ret_count = 0;
184		goto out;
185	}
186	if (offset + ret_count > fw->size)
187		ret_count = fw->size - offset;
188
189	memcpy(buffer, fw->data + offset, ret_count);
190out:
191	up(&fw_lock);
192	return ret_count;
193}
194static int
195fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
196{
197	u8 *new_data;
198
199	if (min_size <= fw_priv->alloc_size)
200		return 0;
201
202	new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE);
203	if (!new_data) {
204		printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
205		/* Make sure that we don't keep incomplete data */
206		fw_load_abort(fw_priv);
207		return -ENOMEM;
208	}
209	fw_priv->alloc_size += PAGE_SIZE;
210	if (fw_priv->fw->data) {
211		memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
212		vfree(fw_priv->fw->data);
213	}
214	fw_priv->fw->data = new_data;
215	BUG_ON(min_size > fw_priv->alloc_size);
216	return 0;
217}
218
219/**
220 * firmware_data_write:
221 *
222 * Description:
223 *
224 *	Data written to the 'data' attribute will be later handled to
225 *	the driver as a firmware image.
226 **/
227static ssize_t
228firmware_data_write(struct kobject *kobj,
229		    char *buffer, loff_t offset, size_t count)
230{
231	struct class_device *class_dev = to_class_dev(kobj);
232	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
233	struct firmware *fw;
234	ssize_t retval;
235
236	if (!capable(CAP_SYS_RAWIO))
237		return -EPERM;
238	down(&fw_lock);
239	fw = fw_priv->fw;
240	if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
241		retval = -ENODEV;
242		goto out;
243	}
244	retval = fw_realloc_buffer(fw_priv, offset + count);
245	if (retval)
246		goto out;
247
248	memcpy(fw->data + offset, buffer, count);
249
250	fw->size = max_t(size_t, offset + count, fw->size);
251	retval = count;
252out:
253	up(&fw_lock);
254	return retval;
255}
256static struct bin_attribute firmware_attr_data_tmpl = {
257	.attr = {.name = "data", .mode = 0644, .owner = THIS_MODULE},
258	.size = 0,
259	.read = firmware_data_read,
260	.write = firmware_data_write,
261};
262
263static void
264fw_class_dev_release(struct class_device *class_dev)
265{
266	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
267
268	kfree(fw_priv);
269	kfree(class_dev);
270
271	module_put(THIS_MODULE);
272}
273
274static void
275firmware_class_timeout(u_long data)
276{
277	struct firmware_priv *fw_priv = (struct firmware_priv *) data;
278	fw_load_abort(fw_priv);
279}
280
281static inline void
282fw_setup_class_device_id(struct class_device *class_dev, struct device *dev)
283{
284	/* XXX warning we should watch out for name collisions */
285	strlcpy(class_dev->class_id, dev->bus_id, BUS_ID_SIZE);
286}
287
288static int
289fw_register_class_device(struct class_device **class_dev_p,
290			 const char *fw_name, struct device *device)
291{
292	int retval;
293	struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
294						GFP_KERNEL);
295	struct class_device *class_dev = kmalloc(sizeof (struct class_device),
296						 GFP_KERNEL);
297
298	*class_dev_p = NULL;
299
300	if (!fw_priv || !class_dev) {
301		printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__);
302		retval = -ENOMEM;
303		goto error_kfree;
304	}
305	memset(fw_priv, 0, sizeof (*fw_priv));
306	memset(class_dev, 0, sizeof (*class_dev));
307
308	init_completion(&fw_priv->completion);
309	fw_priv->attr_data = firmware_attr_data_tmpl;
310	strlcpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX);
311
312	fw_priv->timeout.function = firmware_class_timeout;
313	fw_priv->timeout.data = (u_long) fw_priv;
314	init_timer(&fw_priv->timeout);
315
316	fw_setup_class_device_id(class_dev, device);
317	class_dev->dev = device;
318	class_dev->class = &firmware_class;
319	class_set_devdata(class_dev, fw_priv);
320	retval = class_device_register(class_dev);
321	if (retval) {
322		printk(KERN_ERR "%s: class_device_register failed\n",
323		       __FUNCTION__);
324		goto error_kfree;
325	}
326	*class_dev_p = class_dev;
327	return 0;
328
329error_kfree:
330	kfree(fw_priv);
331	kfree(class_dev);
332	return retval;
333}
334
335static int
336fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
337		      const char *fw_name, struct device *device)
338{
339	struct class_device *class_dev;
340	struct firmware_priv *fw_priv;
341	int retval;
342
343	*class_dev_p = NULL;
344	retval = fw_register_class_device(&class_dev, fw_name, device);
345	if (retval)
346		goto out;
347
348	/* Need to pin this module until class device is destroyed */
349	__module_get(THIS_MODULE);
350
351	fw_priv = class_get_devdata(class_dev);
352
353	fw_priv->fw = fw;
354	retval = sysfs_create_bin_file(&class_dev->kobj, &fw_priv->attr_data);
355	if (retval) {
356		printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
357		       __FUNCTION__);
358		goto error_unreg;
359	}
360
361	retval = class_device_create_file(class_dev,
362					  &class_device_attr_loading);
363	if (retval) {
364		printk(KERN_ERR "%s: class_device_create_file failed\n",
365		       __FUNCTION__);
366		goto error_unreg;
367	}
368
369	set_bit(FW_STATUS_READY, &fw_priv->status);
370	*class_dev_p = class_dev;
371	goto out;
372
373error_unreg:
374	class_device_unregister(class_dev);
375out:
376	return retval;
377}
378
379/**
380 * request_firmware: - request firmware to hotplug and wait for it
381 * Description:
382 *	@firmware will be used to return a firmware image by the name
383 *	of @name for device @device.
384 *
385 *	Should be called from user context where sleeping is allowed.
386 *
387 *	@name will be use as $FIRMWARE in the hotplug environment and
388 *	should be distinctive enough not to be confused with any other
389 *	firmware image for this or any other device.
390 **/
391int
392request_firmware(const struct firmware **firmware_p, const char *name,
393		 struct device *device)
394{
395	struct class_device *class_dev;
396	struct firmware_priv *fw_priv;
397	struct firmware *firmware;
398	int retval;
399
400	if (!firmware_p)
401		return -EINVAL;
402
403	*firmware_p = firmware = kmalloc(sizeof (struct firmware), GFP_KERNEL);
404	if (!firmware) {
405		printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
406		       __FUNCTION__);
407		retval = -ENOMEM;
408		goto out;
409	}
410	memset(firmware, 0, sizeof (*firmware));
411
412	retval = fw_setup_class_device(firmware, &class_dev, name, device);
413	if (retval)
414		goto error_kfree_fw;
415
416	fw_priv = class_get_devdata(class_dev);
417
418	if (loading_timeout) {
419		fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
420		add_timer(&fw_priv->timeout);
421	}
422
423	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
424	wait_for_completion(&fw_priv->completion);
425	set_bit(FW_STATUS_DONE, &fw_priv->status);
426
427	del_timer_sync(&fw_priv->timeout);
428
429	down(&fw_lock);
430	if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
431		retval = -ENOENT;
432		release_firmware(fw_priv->fw);
433		*firmware_p = NULL;
434	}
435	fw_priv->fw = NULL;
436	up(&fw_lock);
437	class_device_unregister(class_dev);
438	goto out;
439
440error_kfree_fw:
441	kfree(firmware);
442	*firmware_p = NULL;
443out:
444	return retval;
445}
446
447/**
448 * release_firmware: - release the resource associated with a firmware image
449 **/
450void
451release_firmware(const struct firmware *fw)
452{
453	if (fw) {
454		vfree(fw->data);
455		kfree(fw);
456	}
457}
458
459/**
460 * register_firmware: - provide a firmware image for later usage
461 *
462 * Description:
463 *	Make sure that @data will be available by requesting firmware @name.
464 *
465 *	Note: This will not be possible until some kind of persistence
466 *	is available.
467 **/
468void
469register_firmware(const char *name, const u8 *data, size_t size)
470{
471	/* This is meaningless without firmware caching, so until we
472	 * decide if firmware caching is reasonable just leave it as a
473	 * noop */
474}
475
476/* Async support */
477struct firmware_work {
478	struct work_struct work;
479	struct module *module;
480	const char *name;
481	struct device *device;
482	void *context;
483	void (*cont)(const struct firmware *fw, void *context);
484};
485
486static int
487request_firmware_work_func(void *arg)
488{
489	struct firmware_work *fw_work = arg;
490	const struct firmware *fw;
491	if (!arg) {
492		WARN_ON(1);
493		return 0;
494	}
495	daemonize("%s/%s", "firmware", fw_work->name);
496	request_firmware(&fw, fw_work->name, fw_work->device);
497	fw_work->cont(fw, fw_work->context);
498	release_firmware(fw);
499	module_put(fw_work->module);
500	kfree(fw_work);
501	return 0;
502}
503
504/**
505 * request_firmware_nowait:
506 *
507 * Description:
508 *	Asynchronous variant of request_firmware() for contexts where
509 *	it is not possible to sleep.
510 *
511 *	@cont will be called asynchronously when the firmware request is over.
512 *
513 *	@context will be passed over to @cont.
514 *
515 *	@fw may be %NULL if firmware request fails.
516 *
517 **/
518int
519request_firmware_nowait(
520	struct module *module,
521	const char *name, struct device *device, void *context,
522	void (*cont)(const struct firmware *fw, void *context))
523{
524	struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
525						GFP_ATOMIC);
526	int ret;
527
528	if (!fw_work)
529		return -ENOMEM;
530	if (!try_module_get(module)) {
531		kfree(fw_work);
532		return -EFAULT;
533	}
534
535	*fw_work = (struct firmware_work) {
536		.module = module,
537		.name = name,
538		.device = device,
539		.context = context,
540		.cont = cont,
541	};
542
543	ret = kernel_thread(request_firmware_work_func, fw_work,
544			    CLONE_FS | CLONE_FILES);
545
546	if (ret < 0) {
547		fw_work->cont(NULL, fw_work->context);
548		return ret;
549	}
550	return 0;
551}
552
553static int __init
554firmware_class_init(void)
555{
556	int error;
557	error = class_register(&firmware_class);
558	if (error) {
559		printk(KERN_ERR "%s: class_register failed\n", __FUNCTION__);
560		return error;
561	}
562	error = class_create_file(&firmware_class, &class_attr_timeout);
563	if (error) {
564		printk(KERN_ERR "%s: class_create_file failed\n",
565		       __FUNCTION__);
566		class_unregister(&firmware_class);
567	}
568	return error;
569
570}
571static void __exit
572firmware_class_exit(void)
573{
574	class_unregister(&firmware_class);
575}
576
577module_init(firmware_class_init);
578module_exit(firmware_class_exit);
579
580EXPORT_SYMBOL(release_firmware);
581EXPORT_SYMBOL(request_firmware);
582EXPORT_SYMBOL(request_firmware_nowait);
583EXPORT_SYMBOL(register_firmware);