Subversion Repositories Kolibri OS

Rev

Rev 1412 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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