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