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