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