Subversion Repositories Kolibri OS

Rev

Rev 1412 | Rev 5270 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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