2005-04-17 02:20:36 +04:00
/*
* firmware_sample_driver . c -
*
* Copyright ( c ) 2003 Manuel Estrada Sainz < ranty @ debian . org >
*
* Sample code on how to use request_firmware ( ) from drivers .
*
* Note that register_firmware ( ) is currently useless .
*
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/device.h>
2005-10-31 02:03:48 +03:00
# include <linux/string.h>
2005-04-17 02:20:36 +04:00
# include "linux/firmware.h"
# define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
# ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
char __init inkernel_firmware [ ] = " let's say that this is firmware \n " ;
# endif
static struct device ghost_device = {
. name = " Ghost Device " ,
. bus_id = " ghost0 " ,
} ;
static void sample_firmware_load ( char * firmware , int size )
{
u8 buf [ size + 1 ] ;
memcpy ( buf , firmware , size ) ;
buf [ size ] = ' \0 ' ;
2005-09-08 10:55:53 +04:00
printk ( KERN_INFO " firmware_sample_driver: firmware: %s \n " , buf ) ;
2005-04-17 02:20:36 +04:00
}
static void sample_probe_default ( void )
{
/* uses the default method to get the firmware */
const struct firmware * fw_entry ;
2005-09-08 10:55:53 +04:00
printk ( KERN_INFO " firmware_sample_driver: a ghost device got inserted :) \n " ) ;
2005-04-17 02:20:36 +04:00
if ( request_firmware ( & fw_entry , " sample_driver_fw " , & ghost_device ) ! = 0 )
{
printk ( KERN_ERR
" firmware_sample_driver: Firmware not available \n " ) ;
return ;
}
sample_firmware_load ( fw_entry - > data , fw_entry - > size ) ;
release_firmware ( fw_entry ) ;
/* finish setting up the device */
}
static void sample_probe_specific ( void )
{
/* 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 */
2005-09-08 10:55:53 +04:00
printk ( KERN_INFO " firmware_sample_driver: a ghost device got inserted :) \n " ) ;
2005-04-17 02:20:36 +04:00
if ( request_firmware ( NULL , " sample_driver_fw " , & ghost_device ) ! = 0 )
{
printk ( KERN_ERR
" firmware_sample_driver: Firmware load failed \n " ) ;
return ;
}
/* request_firmware blocks until userspace finished, so at
* this point the firmware should be already in the device */
/* finish setting up the device */
}
static void sample_probe_async_cont ( const struct firmware * fw , void * context )
{
if ( ! fw ) {
printk ( KERN_ERR
" firmware_sample_driver: firmware load failed \n " ) ;
return ;
}
2005-09-08 10:55:53 +04:00
printk ( KERN_INFO " firmware_sample_driver: device pointer \" %s \" \n " ,
2005-04-17 02:20:36 +04:00
( char * ) context ) ;
sample_firmware_load ( fw - > data , fw - > size ) ;
}
static void sample_probe_async ( void )
{
/* Let's say that I can't sleep */
int error ;
error = request_firmware_nowait ( THIS_MODULE ,
" sample_driver_fw " , & ghost_device ,
" my device pointer " ,
sample_probe_async_cont ) ;
if ( error ) {
printk ( KERN_ERR
" firmware_sample_driver: "
" request_firmware_nowait failed \n " ) ;
}
}
static int sample_init ( void )
{
# ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
register_firmware ( " sample_driver_fw " , inkernel_firmware ,
sizeof ( inkernel_firmware ) ) ;
# endif
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 ;
}
static void __exit sample_exit ( void )
{
}
module_init ( sample_init ) ;
module_exit ( sample_exit ) ;
MODULE_LICENSE ( " GPL " ) ;