]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #include <linux/vmalloc.h> |
2 | #include <linux/module.h> | |
3 | #include <linux/fs.h> | |
434b5a2e | 4 | #include <linux/file.h> |
1da177e4 | 5 | #include <linux/mm.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; | |
1da177e4 LT |
15 | |
16 | filp = filp_open(fn, 0, 0); | |
17 | if (IS_ERR(filp)) | |
18 | { | |
19 | printk(KERN_INFO "Unable to load '%s'.\n", fn); | |
20 | return 0; | |
21 | } | |
496ad9aa | 22 | l = i_size_read(file_inode(filp)); |
1da177e4 LT |
23 | if (l <= 0 || l > 131072) |
24 | { | |
25 | printk(KERN_INFO "Invalid firmware '%s'\n", fn); | |
434b5a2e | 26 | fput(filp); |
1da177e4 LT |
27 | return 0; |
28 | } | |
29 | dp = vmalloc(l); | |
30 | if (dp == NULL) | |
31 | { | |
32 | printk(KERN_INFO "Out of memory loading '%s'.\n", fn); | |
434b5a2e | 33 | fput(filp); |
1da177e4 LT |
34 | return 0; |
35 | } | |
0d769a52 | 36 | if (kernel_read(filp, 0, dp, l) != l) |
1da177e4 LT |
37 | { |
38 | printk(KERN_INFO "Failed to read '%s'.\n", fn); | |
39 | vfree(dp); | |
434b5a2e | 40 | fput(filp); |
1da177e4 LT |
41 | return 0; |
42 | } | |
434b5a2e | 43 | fput(filp); |
1da177e4 LT |
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 | |
b9dd6ffc | 62 | * request_firmware. |
1da177e4 LT |
63 | */ |
64 | ||
65 | int mod_firmware_load(const char *fn, char **fp) | |
66 | { | |
67 | int r; | |
68 | mm_segment_t fs = get_fs(); | |
69 | ||
70 | set_fs(get_ds()); | |
71 | r = do_mod_firmware_load(fn, fp); | |
72 | set_fs(fs); | |
73 | return r; | |
74 | } | |
b9dd6ffc | 75 | EXPORT_SYMBOL(mod_firmware_load); |
1da177e4 | 76 | |
b9dd6ffc | 77 | MODULE_LICENSE("GPL"); |