sound_firmware.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include <linux/vmalloc.h>
  2. #include <linux/module.h>
  3. #include <linux/fs.h>
  4. #include <linux/mm.h>
  5. #include <linux/slab.h>
  6. #include <asm/uaccess.h>
  7. static int do_mod_firmware_load(const char *fn, char **fp)
  8. {
  9. struct file* filp;
  10. long l;
  11. char *dp;
  12. loff_t pos;
  13. filp = filp_open(fn, 0, 0);
  14. if (IS_ERR(filp))
  15. {
  16. printk(KERN_INFO "Unable to load '%s'.\n", fn);
  17. return 0;
  18. }
  19. l = filp->f_dentry->d_inode->i_size;
  20. if (l <= 0 || l > 131072)
  21. {
  22. printk(KERN_INFO "Invalid firmware '%s'\n", fn);
  23. filp_close(filp, current->files);
  24. return 0;
  25. }
  26. dp = vmalloc(l);
  27. if (dp == NULL)
  28. {
  29. printk(KERN_INFO "Out of memory loading '%s'.\n", fn);
  30. filp_close(filp, current->files);
  31. return 0;
  32. }
  33. pos = 0;
  34. if (vfs_read(filp, dp, l, &pos) != l)
  35. {
  36. printk(KERN_INFO "Failed to read '%s'.\n", fn);
  37. vfree(dp);
  38. filp_close(filp, current->files);
  39. return 0;
  40. }
  41. filp_close(filp, current->files);
  42. *fp = dp;
  43. return (int) l;
  44. }
  45. /**
  46. * mod_firmware_load - load sound driver firmware
  47. * @fn: filename
  48. * @fp: return for the buffer.
  49. *
  50. * Load the firmware for a sound module (up to 128K) into a buffer.
  51. * The buffer is returned in *fp. It is allocated with vmalloc so is
  52. * virtually linear and not DMAable. The caller should free it with
  53. * vfree when finished.
  54. *
  55. * The length of the buffer is returned on a successful load, the
  56. * value zero on a failure.
  57. *
  58. * Caution: This API is not recommended. Firmware should be loaded via
  59. * an ioctl call and a setup application. This function may disappear
  60. * in future.
  61. */
  62. int mod_firmware_load(const char *fn, char **fp)
  63. {
  64. int r;
  65. mm_segment_t fs = get_fs();
  66. set_fs(get_ds());
  67. r = do_mod_firmware_load(fn, fp);
  68. set_fs(fs);
  69. return r;
  70. }