Subversion Repositories Kolibri OS

Rev

Rev 5270 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <linux/kernel.h>
  3. #include <linux/slab.h>
  4. #include <linux/byteorder/little_endian.h>
  5. #include <linux/gfp.h>
  6. #include <linux/errno.h>
  7. #include <linux/firmware.h>
  8.  
  9. extern struct builtin_fw __start_builtin_fw[];
  10. extern struct builtin_fw __end_builtin_fw[];
  11.  
  12. /* Intel HEX files actually limit the length to 256 bytes, but we have
  13.    drivers which would benefit from using separate records which are
  14.    longer than that, so we extend to 16 bits of length */
  15. struct ihex_binrec {
  16.     __be32      addr;
  17.     __be16      len;
  18.     uint8_t     data[0];
  19. } __attribute__((packed));
  20.  
  21. /* Find the next record, taking into account the 4-byte alignment */
  22. static inline const struct ihex_binrec *
  23. ihex_next_binrec(const struct ihex_binrec *rec)
  24. {
  25.     int next = ((be16_to_cpu(rec->len) + 5) & ~3) - 2;
  26.     rec = (void *)&rec->data[next];
  27.  
  28.     return be16_to_cpu(rec->len) ? rec : NULL;
  29. }
  30.  
  31. int
  32. request_firmware(const struct firmware **firmware_p, const char *name,
  33.                  struct device *device)
  34. {
  35.  
  36.     struct firmware *firmware;
  37.     struct builtin_fw *builtin;
  38.     const struct ihex_binrec *rec;
  39.     unsigned int size;
  40.  
  41.     int retval;
  42.  
  43.     if (!firmware_p)
  44.         return -EINVAL;
  45.  
  46.     *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
  47.     if (!firmware) {
  48.         dbgprintf("%s: kmalloc(struct firmware) failed\n", __func__);
  49.         return  -ENOMEM;
  50.     }
  51.  
  52.     for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
  53.          builtin++)
  54.     {
  55.         uint8_t  *pfw;
  56.  
  57.         if (strcmp(name, builtin->name))
  58.             continue;
  59.         dbgprintf("firmware: using built-in firmware %s\n", name);
  60.  
  61. #if 0
  62.         size = 0;
  63.         for (rec = (const struct ihex_binrec *)builtin->data;
  64.              rec; rec = ihex_next_binrec(rec))
  65.         {
  66.             size += be16_to_cpu(rec->len);
  67.         }
  68.         dbgprintf("firmware size %d\n", size);
  69.  
  70.         if(unlikely( size == 0))
  71.             return -EINVAL;
  72.  
  73.  
  74.         pfw = (uint8_t*)kzalloc(size, 0);
  75.  
  76.         if(unlikely(pfw == 0))
  77.             return -ENOMEM;
  78.  
  79.         firmware->size = size;
  80.         firmware->data = pfw;
  81.  
  82.         for (rec = (const struct ihex_binrec *)builtin->data;
  83.              rec; rec = ihex_next_binrec(rec))
  84.         {
  85.             unsigned int src_size;
  86.  
  87.             src_size = be16_to_cpu(rec->len);
  88.             memcpy(pfw, rec->data, src_size);
  89.             pfw+= src_size;
  90.         };
  91. #else
  92.         dbgprintf("firmware size %d\n", builtin->size);
  93.  
  94.         firmware->size = builtin->size;
  95.         firmware->data = builtin->data;
  96. #endif
  97.         return 0;
  98.     }
  99.  
  100.     kfree(firmware);
  101.     *firmware_p = NULL;
  102.  
  103.     return -EINVAL;
  104. };
  105.  
  106. void
  107. release_firmware(const struct firmware *fw)
  108. {
  109.     if (fw) {
  110.         kfree((void*)fw);
  111.     }
  112. }
  113. /*
  114. struct platform_device*
  115. platform_device_register_simple(const char* c, int id, void *r, unsigned int i)
  116. {
  117.     static struct platform_device pd;
  118.  
  119.     return &pd;
  120. };
  121. */
  122.  
  123.