Blame view
samples/firmware_class/firmware_sample_driver.c
2.75 KB
1da177e4c
|
1 2 3 |
/* * firmware_sample_driver.c - * |
87d37a4f4
|
4 |
* Copyright (c) 2003 Manuel Estrada Sainz |
1da177e4c
|
5 6 7 |
* * Sample code on how to use request_firmware() from drivers. * |
1da177e4c
|
8 9 10 11 12 13 |
*/ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/device.h> |
4e57b6817
|
14 |
#include <linux/string.h> |
4b65fc8cf
|
15 |
#include <linux/firmware.h> |
1da177e4c
|
16 |
|
1da177e4c
|
17 |
static struct device ghost_device = { |
1da177e4c
|
18 19 20 21 22 23 24 25 26 |
.bus_id = "ghost0", }; static void sample_firmware_load(char *firmware, int size) { u8 buf[size+1]; memcpy(buf, firmware, size); buf[size] = '\0'; |
20dd026d7
|
27 28 |
printk(KERN_INFO "firmware_sample_driver: firmware: %s ", buf); |
1da177e4c
|
29 30 31 32 33 |
} static void sample_probe_default(void) { /* uses the default method to get the firmware */ |
4b65fc8cf
|
34 35 36 37 38 39 |
const struct firmware *fw_entry; int retval; printk(KERN_INFO "firmware_sample_driver: " "a ghost device got inserted :) "); |
1da177e4c
|
40 |
|
4b65fc8cf
|
41 42 |
retval = request_firmware(&fw_entry, "sample_driver_fw", &ghost_device); if (retval) { |
1da177e4c
|
43 44 45 46 47 |
printk(KERN_ERR "firmware_sample_driver: Firmware not available "); return; } |
d289bf7bd
|
48 |
|
1da177e4c
|
49 50 51 52 53 54 |
sample_firmware_load(fw_entry->data, fw_entry->size); release_firmware(fw_entry); /* finish setting up the device */ } |
4b65fc8cf
|
55 |
|
1da177e4c
|
56 57 |
static void sample_probe_specific(void) { |
4b65fc8cf
|
58 |
int retval; |
1da177e4c
|
59 60 61 62 |
/* Uses some specific hotplug support to get the firmware from * userspace directly into the hardware, or via some sysfs file */ /* NOTE: This currently doesn't work */ |
4b65fc8cf
|
63 64 65 |
printk(KERN_INFO "firmware_sample_driver: " "a ghost device got inserted :) "); |
1da177e4c
|
66 |
|
4b65fc8cf
|
67 68 |
retval = request_firmware(NULL, "sample_driver_fw", &ghost_device); if (retval) { |
1da177e4c
|
69 70 71 72 73 |
printk(KERN_ERR "firmware_sample_driver: Firmware load failed "); return; } |
d289bf7bd
|
74 |
|
1da177e4c
|
75 76 77 78 79 |
/* request_firmware blocks until userspace finished, so at * this point the firmware should be already in the device */ /* finish setting up the device */ } |
e9b62693a
|
80 |
|
1da177e4c
|
81 82 |
static void sample_probe_async_cont(const struct firmware *fw, void *context) { |
4b65fc8cf
|
83 |
if (!fw) { |
1da177e4c
|
84 85 86 87 88 |
printk(KERN_ERR "firmware_sample_driver: firmware load failed "); return; } |
20dd026d7
|
89 90 |
printk(KERN_INFO "firmware_sample_driver: device pointer \"%s\" ", |
1da177e4c
|
91 92 93 |
(char *)context); sample_firmware_load(fw->data, fw->size); } |
4b65fc8cf
|
94 |
|
1da177e4c
|
95 96 97 98 |
static void sample_probe_async(void) { /* Let's say that I can't sleep */ int error; |
4b65fc8cf
|
99 100 101 102 103 104 |
error = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, "sample_driver_fw", &ghost_device, "my device pointer", sample_probe_async_cont); if (error) printk(KERN_ERR "firmware_sample_driver:" |
1da177e4c
|
105 106 |
" request_firmware_nowait failed "); |
1da177e4c
|
107 108 109 110 |
} static int sample_init(void) { |
1da177e4c
|
111 112 113 114 115 116 117 118 |
device_initialize(&ghost_device); /* since there is no real hardware insertion I just call the * sample probe functions here */ sample_probe_specific(); sample_probe_default(); sample_probe_async(); return 0; } |
4b65fc8cf
|
119 |
|
1da177e4c
|
120 121 122 |
static void __exit sample_exit(void) { } |
4b65fc8cf
|
123 124 |
module_init(sample_init); module_exit(sample_exit); |
1da177e4c
|
125 126 |
MODULE_LICENSE("GPL"); |