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