#include <linux/device.h>
#include <linux/firmware.h>

static DECLARE_COMPLETION( obj_not_in_use );

static void firmware_device_release( struct device *dev )
{
       complete( &obj_not_in_use );
}

static struct device fwasync_device = {
       .bus_id    = "fwasync",
       .release   = firmware_device_release,
};

static void fwasync_cont(const struct firmware *fw, void *private_data)
{
       unsigned char buf[80+1];
       int to_copy;

       if(fw==NULL){
               printk("fwasync_cont: firmware load failed\n");
               return;
       }
       to_copy = min( (sizeof(buf)-1), fw->size );
       memcpy(buf, fw->data, to_copy);
       buf[to_copy] = '\0';
       printk("firmware(%d): \"%s\"\n", (int)fw->size, buf);
}

static int __init fwasync_init(void)
{
       if( device_register( &fwasync_device ) ) {
               printk("device_register failed\n");
               return -EIO;
       }
       if( request_firmware_nowait(THIS_MODULE,
               FW_ACTION_NOHOTPLUG,
               "pseudo_firmware", &fwasync_device,
               "private_data", fwasync_cont) ) {
               printk("fwasync: request_firmware_nowait failed\n");
               device_unregister( &fwasync_device );
               return -EIO;
       }
       return 0;
}

static void __exit fwasync_exit(void)
{
       device_unregister( &fwasync_device );
       wait_for_completion( &obj_not_in_use );
}

module_init(fwasync_init);
module_exit(fwasync_exit);
MODULE_LICENSE("GPL");