aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-06-04 03:54:43 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-05 16:53:34 -0400
commitf8a4bd3456b988fc73b2c291b9e01b434c8fa940 (patch)
tree9e45a2c9a65fe87632dbcfde479aa456e6cae67a /drivers/base/firmware_class.c
parent0983ca2d0f0ff645bc86899aefb936cffb314839 (diff)
firmware loader: embed device into firmware_priv structure
Both these structures have the same lifetime rules so instead of allocating and managing them separately embed struct device into struct firmware_priv. Also make sure to delete sysfs attributes ourselves instead of expecting sysfs to clean up our mess. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c255
1 files changed, 122 insertions, 133 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index fb29c64ebecc..c8a44f5e0584 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -93,22 +93,26 @@ struct firmware_priv {
93 int nr_pages; 93 int nr_pages;
94 int page_array_size; 94 int page_array_size;
95 struct timer_list timeout; 95 struct timer_list timeout;
96 struct device dev;
96 bool nowait; 97 bool nowait;
97 char fw_id[]; 98 char fw_id[];
98}; 99};
99 100
100static void 101static struct firmware_priv *to_firmware_priv(struct device *dev)
101fw_load_abort(struct firmware_priv *fw_priv) 102{
103 return container_of(dev, struct firmware_priv, dev);
104}
105
106static void fw_load_abort(struct firmware_priv *fw_priv)
102{ 107{
103 set_bit(FW_STATUS_ABORT, &fw_priv->status); 108 set_bit(FW_STATUS_ABORT, &fw_priv->status);
104 wmb(); 109 wmb();
105 complete(&fw_priv->completion); 110 complete(&fw_priv->completion);
106} 111}
107 112
108static ssize_t 113static ssize_t firmware_timeout_show(struct class *class,
109firmware_timeout_show(struct class *class, 114 struct class_attribute *attr,
110 struct class_attribute *attr, 115 char *buf)
111 char *buf)
112{ 116{
113 return sprintf(buf, "%d\n", loading_timeout); 117 return sprintf(buf, "%d\n", loading_timeout);
114} 118}
@@ -126,14 +130,14 @@ firmware_timeout_show(struct class *class,
126 * 130 *
127 * Note: zero means 'wait forever'. 131 * Note: zero means 'wait forever'.
128 **/ 132 **/
129static ssize_t 133static ssize_t firmware_timeout_store(struct class *class,
130firmware_timeout_store(struct class *class, 134 struct class_attribute *attr,
131 struct class_attribute *attr, 135 const char *buf, size_t count)
132 const char *buf, size_t count)
133{ 136{
134 loading_timeout = simple_strtol(buf, NULL, 10); 137 loading_timeout = simple_strtol(buf, NULL, 10);
135 if (loading_timeout < 0) 138 if (loading_timeout < 0)
136 loading_timeout = 0; 139 loading_timeout = 0;
140
137 return count; 141 return count;
138} 142}
139 143
@@ -145,21 +149,20 @@ static struct class_attribute firmware_class_attrs[] = {
145 149
146static void fw_dev_release(struct device *dev) 150static void fw_dev_release(struct device *dev)
147{ 151{
148 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 152 struct firmware_priv *fw_priv = to_firmware_priv(dev);
149 int i; 153 int i;
150 154
151 for (i = 0; i < fw_priv->nr_pages; i++) 155 for (i = 0; i < fw_priv->nr_pages; i++)
152 __free_page(fw_priv->pages[i]); 156 __free_page(fw_priv->pages[i]);
153 kfree(fw_priv->pages); 157 kfree(fw_priv->pages);
154 kfree(fw_priv); 158 kfree(fw_priv);
155 kfree(dev);
156 159
157 module_put(THIS_MODULE); 160 module_put(THIS_MODULE);
158} 161}
159 162
160static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) 163static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
161{ 164{
162 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 165 struct firmware_priv *fw_priv = to_firmware_priv(dev);
163 166
164 if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id)) 167 if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id))
165 return -ENOMEM; 168 return -ENOMEM;
@@ -181,8 +184,9 @@ static struct class firmware_class = {
181static ssize_t firmware_loading_show(struct device *dev, 184static ssize_t firmware_loading_show(struct device *dev,
182 struct device_attribute *attr, char *buf) 185 struct device_attribute *attr, char *buf)
183{ 186{
184 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 187 struct firmware_priv *fw_priv = to_firmware_priv(dev);
185 int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); 188 int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status);
189
186 return sprintf(buf, "%d\n", loading); 190 return sprintf(buf, "%d\n", loading);
187} 191}
188 192
@@ -218,7 +222,7 @@ static ssize_t firmware_loading_store(struct device *dev,
218 struct device_attribute *attr, 222 struct device_attribute *attr,
219 const char *buf, size_t count) 223 const char *buf, size_t count)
220{ 224{
221 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 225 struct firmware_priv *fw_priv = to_firmware_priv(dev);
222 int loading = simple_strtol(buf, NULL, 10); 226 int loading = simple_strtol(buf, NULL, 10);
223 int i; 227 int i;
224 228
@@ -276,13 +280,12 @@ static ssize_t firmware_loading_store(struct device *dev,
276 280
277static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); 281static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
278 282
279static ssize_t 283static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj,
280firmware_data_read(struct file *filp, struct kobject *kobj, 284 struct bin_attribute *bin_attr,
281 struct bin_attribute *bin_attr, char *buffer, loff_t offset, 285 char *buffer, loff_t offset, size_t count)
282 size_t count)
283{ 286{
284 struct device *dev = to_dev(kobj); 287 struct device *dev = to_dev(kobj);
285 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 288 struct firmware_priv *fw_priv = to_firmware_priv(dev);
286 struct firmware *fw; 289 struct firmware *fw;
287 ssize_t ret_count; 290 ssize_t ret_count;
288 291
@@ -321,8 +324,7 @@ out:
321 return ret_count; 324 return ret_count;
322} 325}
323 326
324static int 327static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
325fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
326{ 328{
327 int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT; 329 int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT;
328 330
@@ -372,13 +374,12 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
372 * Data written to the 'data' attribute will be later handed to 374 * Data written to the 'data' attribute will be later handed to
373 * the driver as a firmware image. 375 * the driver as a firmware image.
374 **/ 376 **/
375static ssize_t 377static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
376firmware_data_write(struct file* filp, struct kobject *kobj, 378 struct bin_attribute *bin_attr,
377 struct bin_attribute *bin_attr, char *buffer, 379 char *buffer, loff_t offset, size_t count)
378 loff_t offset, size_t count)
379{ 380{
380 struct device *dev = to_dev(kobj); 381 struct device *dev = to_dev(kobj);
381 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 382 struct firmware_priv *fw_priv = to_firmware_priv(dev);
382 struct firmware *fw; 383 struct firmware *fw;
383 ssize_t retval; 384 ssize_t retval;
384 385
@@ -426,107 +427,96 @@ static struct bin_attribute firmware_attr_data = {
426 .write = firmware_data_write, 427 .write = firmware_data_write,
427}; 428};
428 429
429static void 430static void firmware_class_timeout(u_long data)
430firmware_class_timeout(u_long data)
431{ 431{
432 struct firmware_priv *fw_priv = (struct firmware_priv *) data; 432 struct firmware_priv *fw_priv = (struct firmware_priv *) data;
433
433 fw_load_abort(fw_priv); 434 fw_load_abort(fw_priv);
434} 435}
435 436
436static int fw_register_device(struct device **dev_p, const char *fw_name, 437static struct firmware_priv *
437 struct device *device) 438fw_create_instance(struct firmware *firmware, const char *fw_name,
439 struct device *device, bool uevent, bool nowait)
438{ 440{
439 int retval; 441 struct firmware_priv *fw_priv;
440 struct firmware_priv *fw_priv = 442 struct device *f_dev;
441 kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL); 443 int error;
442 struct device *f_dev = kzalloc(sizeof(*f_dev), GFP_KERNEL);
443
444 *dev_p = NULL;
445 444
446 if (!fw_priv || !f_dev) { 445 fw_priv = kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL);
446 if (!fw_priv) {
447 dev_err(device, "%s: kmalloc failed\n", __func__); 447 dev_err(device, "%s: kmalloc failed\n", __func__);
448 retval = -ENOMEM; 448 error = -ENOMEM;
449 goto error_kfree; 449 goto err_out;
450 } 450 }
451 451
452 fw_priv->fw = firmware;
453 fw_priv->nowait = nowait;
452 strcpy(fw_priv->fw_id, fw_name); 454 strcpy(fw_priv->fw_id, fw_name);
453 init_completion(&fw_priv->completion); 455 init_completion(&fw_priv->completion);
454 fw_priv->timeout.function = firmware_class_timeout; 456 setup_timer(&fw_priv->timeout,
455 fw_priv->timeout.data = (u_long) fw_priv; 457 firmware_class_timeout, (u_long) fw_priv);
456 init_timer(&fw_priv->timeout);
457 458
459 f_dev = &fw_priv->dev;
460
461 device_initialize(f_dev);
458 dev_set_name(f_dev, "%s", dev_name(device)); 462 dev_set_name(f_dev, "%s", dev_name(device));
459 f_dev->parent = device; 463 f_dev->parent = device;
460 f_dev->class = &firmware_class; 464 f_dev->class = &firmware_class;
461 dev_set_drvdata(f_dev, fw_priv);
462 dev_set_uevent_suppress(f_dev, 1);
463 retval = device_register(f_dev);
464 if (retval) {
465 dev_err(device, "%s: device_register failed\n", __func__);
466 put_device(f_dev);
467 return retval;
468 }
469 *dev_p = f_dev;
470 return 0;
471
472error_kfree:
473 kfree(f_dev);
474 kfree(fw_priv);
475 return retval;
476}
477 465
478static int fw_setup_device(struct firmware *fw, struct device **dev_p, 466 dev_set_uevent_suppress(f_dev, true);
479 const char *fw_name, struct device *device,
480 int uevent, bool nowait)
481{
482 struct device *f_dev;
483 struct firmware_priv *fw_priv;
484 int retval;
485
486 *dev_p = NULL;
487 retval = fw_register_device(&f_dev, fw_name, device);
488 if (retval)
489 goto out;
490 467
491 /* Need to pin this module until class device is destroyed */ 468 /* Need to pin this module until class device is destroyed */
492 __module_get(THIS_MODULE); 469 __module_get(THIS_MODULE);
493 470
494 fw_priv = dev_get_drvdata(f_dev); 471 error = device_add(f_dev);
495 472 if (error) {
496 fw_priv->nowait = nowait; 473 dev_err(device, "%s: device_register failed\n", __func__);
474 goto err_put_dev;
475 }
497 476
498 fw_priv->fw = fw; 477 error = device_create_bin_file(f_dev, &firmware_attr_data);
499 retval = sysfs_create_bin_file(&f_dev->kobj, &firmware_attr_data); 478 if (error) {
500 if (retval) {
501 dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__); 479 dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
502 goto error_unreg; 480 goto err_del_dev;
503 } 481 }
504 482
505 retval = device_create_file(f_dev, &dev_attr_loading); 483 error = device_create_file(f_dev, &dev_attr_loading);
506 if (retval) { 484 if (error) {
507 dev_err(device, "%s: device_create_file failed\n", __func__); 485 dev_err(device, "%s: device_create_file failed\n", __func__);
508 goto error_unreg; 486 goto err_del_bin_attr;
509 } 487 }
510 488
511 if (uevent) 489 if (uevent)
512 dev_set_uevent_suppress(f_dev, 0); 490 dev_set_uevent_suppress(f_dev, false);
513 *dev_p = f_dev; 491
514 goto out; 492 return fw_priv;
493
494err_del_bin_attr:
495 device_remove_bin_file(f_dev, &firmware_attr_data);
496err_del_dev:
497 device_del(f_dev);
498err_put_dev:
499 put_device(f_dev);
500err_out:
501 return ERR_PTR(error);
502}
503
504static void fw_destroy_instance(struct firmware_priv *fw_priv)
505{
506 struct device *f_dev = &fw_priv->dev;
515 507
516error_unreg: 508 device_remove_file(f_dev, &dev_attr_loading);
509 device_remove_bin_file(f_dev, &firmware_attr_data);
517 device_unregister(f_dev); 510 device_unregister(f_dev);
518out:
519 return retval;
520} 511}
521 512
522static int 513static int _request_firmware(const struct firmware **firmware_p,
523_request_firmware(const struct firmware **firmware_p, const char *name, 514 const char *name, struct device *device,
524 struct device *device, int uevent, bool nowait) 515 bool uevent, bool nowait)
525{ 516{
526 struct device *f_dev;
527 struct firmware_priv *fw_priv; 517 struct firmware_priv *fw_priv;
528 struct firmware *firmware; 518 struct firmware *firmware;
529 int retval; 519 int retval = 0;
530 520
531 if (!firmware_p) 521 if (!firmware_p)
532 return -EINVAL; 522 return -EINVAL;
@@ -547,41 +537,40 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
547 if (uevent) 537 if (uevent)
548 dev_dbg(device, "firmware: requesting %s\n", name); 538 dev_dbg(device, "firmware: requesting %s\n", name);
549 539
550 retval = fw_setup_device(firmware, &f_dev, name, device, 540 fw_priv = fw_create_instance(firmware, name, device, uevent, nowait);
551 uevent, nowait); 541 if (IS_ERR(fw_priv)) {
552 if (retval) 542 retval = PTR_ERR(fw_priv);
553 goto error_kfree_fw; 543 goto out;
554 544 }
555 fw_priv = dev_get_drvdata(f_dev);
556 545
557 if (uevent) { 546 if (uevent) {
558 if (loading_timeout > 0) { 547 if (loading_timeout > 0)
559 fw_priv->timeout.expires = jiffies + loading_timeout * HZ; 548 mod_timer(&fw_priv->timeout,
560 add_timer(&fw_priv->timeout); 549 round_jiffies_up(jiffies +
561 } 550 loading_timeout * HZ));
551
552 kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
553 }
554
555 wait_for_completion(&fw_priv->completion);
562 556
563 kobject_uevent(&f_dev->kobj, KOBJ_ADD); 557 set_bit(FW_STATUS_DONE, &fw_priv->status);
564 wait_for_completion(&fw_priv->completion); 558 del_timer_sync(&fw_priv->timeout);
565 set_bit(FW_STATUS_DONE, &fw_priv->status);
566 del_timer_sync(&fw_priv->timeout);
567 } else
568 wait_for_completion(&fw_priv->completion);
569 559
570 mutex_lock(&fw_lock); 560 mutex_lock(&fw_lock);
571 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) { 561 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status))
572 retval = -ENOENT; 562 retval = -ENOENT;
573 release_firmware(fw_priv->fw);
574 *firmware_p = NULL;
575 }
576 fw_priv->fw = NULL; 563 fw_priv->fw = NULL;
577 mutex_unlock(&fw_lock); 564 mutex_unlock(&fw_lock);
578 device_unregister(f_dev);
579 goto out;
580 565
581error_kfree_fw: 566 fw_destroy_instance(fw_priv);
582 kfree(firmware); 567
583 *firmware_p = NULL;
584out: 568out:
569 if (retval) {
570 release_firmware(firmware);
571 firmware_p = NULL;
572 }
573
585 return retval; 574 return retval;
586} 575}
587 576
@@ -632,23 +621,24 @@ struct firmware_work {
632 int uevent; 621 int uevent;
633}; 622};
634 623
635static int 624static int request_firmware_work_func(void *arg)
636request_firmware_work_func(void *arg)
637{ 625{
638 struct firmware_work *fw_work = arg; 626 struct firmware_work *fw_work = arg;
639 const struct firmware *fw; 627 const struct firmware *fw;
640 int ret; 628 int ret;
629
641 if (!arg) { 630 if (!arg) {
642 WARN_ON(1); 631 WARN_ON(1);
643 return 0; 632 return 0;
644 } 633 }
645 ret = _request_firmware(&fw, fw_work->name, fw_work->device,
646 fw_work->uevent, true);
647 634
635 ret = _request_firmware(&fw, fw_work->name, fw_work->device,
636 fw_work->uevent, true);
648 fw_work->cont(fw, fw_work->context); 637 fw_work->cont(fw, fw_work->context);
649 638
650 module_put(fw_work->module); 639 module_put(fw_work->module);
651 kfree(fw_work); 640 kfree(fw_work);
641
652 return ret; 642 return ret;
653} 643}
654 644
@@ -676,34 +666,33 @@ request_firmware_nowait(
676 void (*cont)(const struct firmware *fw, void *context)) 666 void (*cont)(const struct firmware *fw, void *context))
677{ 667{
678 struct task_struct *task; 668 struct task_struct *task;
679 struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), 669 struct firmware_work *fw_work;
680 gfp);
681 670
671 fw_work = kzalloc(sizeof (struct firmware_work), gfp);
682 if (!fw_work) 672 if (!fw_work)
683 return -ENOMEM; 673 return -ENOMEM;
674
675 fw_work->module = module;
676 fw_work->name = name;
677 fw_work->device = device;
678 fw_work->context = context;
679 fw_work->cont = cont;
680 fw_work->uevent = uevent;
681
684 if (!try_module_get(module)) { 682 if (!try_module_get(module)) {
685 kfree(fw_work); 683 kfree(fw_work);
686 return -EFAULT; 684 return -EFAULT;
687 } 685 }
688 686
689 *fw_work = (struct firmware_work) {
690 .module = module,
691 .name = name,
692 .device = device,
693 .context = context,
694 .cont = cont,
695 .uevent = uevent,
696 };
697
698 task = kthread_run(request_firmware_work_func, fw_work, 687 task = kthread_run(request_firmware_work_func, fw_work,
699 "firmware/%s", name); 688 "firmware/%s", name);
700
701 if (IS_ERR(task)) { 689 if (IS_ERR(task)) {
702 fw_work->cont(NULL, fw_work->context); 690 fw_work->cont(NULL, fw_work->context);
703 module_put(fw_work->module); 691 module_put(fw_work->module);
704 kfree(fw_work); 692 kfree(fw_work);
705 return PTR_ERR(task); 693 return PTR_ERR(task);
706 } 694 }
695
707 return 0; 696 return 0;
708} 697}
709 698