/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to driver/sysfs.c

  • Committer: Suren A. Chilingaryan
  • Date: 2016-03-02 18:37:30 UTC
  • Revision ID: csa@suren.me-20160302183730-nlrgi7h3yuizcizc
Restructure driver headers

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#include <linux/pagemap.h>
19
19
#include <linux/kernel.h>
20
20
 
21
 
#include "compat.h"
22
 
#include "config.h"
23
 
#include "pciDriver.h"
24
 
#include "common.h"
25
 
#include "umem.h"
26
 
#include "kmem.h"
27
 
#include "sysfs.h"
28
 
 
29
 
static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry);
30
 
static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry);
31
 
 
32
 
/**
33
 
 *
34
 
 * Initializes the sysfs attributes for an kmem/umem-entry
35
 
 *
36
 
 */
37
 
static int _pcidriver_sysfs_initialize(pcidriver_privdata_t *privdata,
38
 
                                       int id,
39
 
                                       struct class_device_attribute *sysfs_attr,
40
 
                                       const char *fmtstring,
41
 
                                       SYSFS_GET_FUNCTION((*callback)))
42
 
{
43
 
    /* sysfs attributes for kmem buffers don’t make sense before 2.6.13, as
44
 
       we have no mmap support before */
45
 
    char namebuffer[16];
46
 
 
47
 
    /* allocate space for the name of the attribute */
48
 
    snprintf(namebuffer, sizeof(namebuffer), fmtstring, id);
49
 
 
50
 
    if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL)
51
 
        return -ENOMEM;
52
 
 
53
 
    sysfs_attr->attr.mode = S_IRUGO;
54
 
    sysfs_attr->show = callback;
55
 
    sysfs_attr->store = NULL;
56
 
 
57
 
    /* name and add attribute */
58
 
    if (class_device_create_file(privdata->class_dev, sysfs_attr) != 0)
59
 
        return -ENXIO; /* Device not configured. Not the really best choice, but hm. */
60
 
 
61
 
    return 0;
62
 
}
63
 
 
64
 
int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr)
65
 
{
66
 
    return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "kbuf%d", pcidriver_show_kmem_entry);
67
 
}
68
 
 
69
 
int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr)
70
 
{
71
 
    return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry);
72
 
}
73
 
 
74
 
/**
75
 
 *
76
 
 * Removes the file from sysfs and frees the allocated (kstrdup()) memory.
77
 
 *
78
 
 */
79
 
void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct class_device_attribute *sysfs_attr)
80
 
{
81
 
    class_device_remove_file(privdata->class_dev, sysfs_attr);
82
 
    kfree(sysfs_attr->attr.name);
83
 
}
84
 
 
85
 
static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry)
86
 
{
87
 
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
88
 
 
89
 
    /* As we can be sure that attr.name contains a filename which we
90
 
     * created (see _pcidriver_sysfs_initialize), we do not need to have
91
 
     * sanity checks but can directly call simple_strtol() */
92
 
    int id = simple_strtol(attr->attr.name + strlen("kbuf"), NULL, 10);
93
 
    pcidriver_kmem_entry_t *entry = pcidriver_kmem_find_entry_id(privdata, id);
94
 
    if (entry) {
95
 
        unsigned long addr = entry->cpua;
96
 
        unsigned long dma_addr = entry->dma_handle;
97
 
 
98
 
        if (entry->size >= 16) {
99
 
            pcidriver_kmem_sync_entry(privdata, entry, PCILIB_KMEM_SYNC_FROMDEVICE);
100
 
            return snprintf(buf, PAGE_SIZE, "buffer: %d\naddr: %lx\nhw addr: %llx\nbus addr: %lx\ntype: %lx\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\ndata: %8x %8x %8x %8x\n", id, addr, virt_to_phys((void*)addr), dma_addr, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode, *(u32*)(entry->cpua), *(u32*)(entry->cpua + 4),  *(u32*)(entry->cpua + 8), *(u32*)(entry->cpua + 12));
101
 
        } else
102
 
            return snprintf(buf, PAGE_SIZE, "buffer: %d\naddr: %lx\nhw addr: %llx\nbus addr: %lx\ntype: %lx\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\n", id, addr, virt_to_phys((void*)addr), dma_addr, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode);
103
 
    } else
104
 
        return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id);
105
 
}
106
 
 
107
 
static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry)
108
 
{
109
 
    return 0;
110
 
}
 
21
#include "base.h"
 
22
 
 
23
#define SYSFS_GET_PRIVDATA dev_get_drvdata(dev)
 
24
#define SYSFS_GET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, char *buf)
 
25
#define SYSFS_SET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 
26
 
 
27
#define SYSFS_ATTR_NAME(name) (dev_attr_##name)
 
28
 
 
29
#define SYSFS_ATTR_CREATE(name) do { \
 
30
        int err = device_create_file(privdata->class_dev, &SYSFS_ATTR_NAME(name)); \
 
31
        if (err != 0) return err; \
 
32
    } while (0)
 
33
 
 
34
#define SYSFS_ATTR_REMOVE(name) do { \
 
35
        device_remove_file(privdata->class_dev, &SYSFS_ATTR_NAME(name)); \
 
36
    } while (0)
111
37
 
112
38
#ifdef ENABLE_IRQ
113
 
SYSFS_GET_FUNCTION(pcidriver_show_irq_count)
 
39
static SYSFS_GET_FUNCTION(pcidriver_show_irq_count)
114
40
{
115
41
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
116
42
 
117
43
    return snprintf(buf, PAGE_SIZE, "%d\n", privdata->irq_count);
118
44
}
119
45
 
120
 
SYSFS_GET_FUNCTION(pcidriver_show_irq_queues)
 
46
static SYSFS_GET_FUNCTION(pcidriver_show_irq_queues)
121
47
{
122
48
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
123
49
    int i, offset;
131
57
}
132
58
#endif
133
59
 
134
 
SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode)
 
60
static SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode)
135
61
{
136
62
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
137
63
 
138
64
    return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_mode);
139
65
}
140
66
 
141
 
SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode)
 
67
static SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode)
142
68
{
143
69
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
144
70
    int mode = -1;
151
77
    return strlen(buf);
152
78
}
153
79
 
154
 
SYSFS_GET_FUNCTION(pcidriver_show_mmap_area)
 
80
static SYSFS_GET_FUNCTION(pcidriver_show_mmap_area)
155
81
{
156
82
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
157
83
 
158
84
    return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_area);
159
85
}
160
86
 
161
 
SYSFS_SET_FUNCTION(pcidriver_store_mmap_area)
 
87
static SYSFS_SET_FUNCTION(pcidriver_store_mmap_area)
162
88
{
163
89
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
164
90
    int temp = -1;
171
97
    return strlen(buf);
172
98
}
173
99
 
174
 
SYSFS_GET_FUNCTION(pcidriver_show_kmem_count)
 
100
static SYSFS_GET_FUNCTION(pcidriver_show_kmem_count)
175
101
{
176
102
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
177
103
 
178
104
    return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&(privdata->kmem_count)));
179
105
}
180
106
 
181
 
SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc)
 
107
static SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc)
182
108
{
183
109
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
184
110
    kmem_handle_t kmem_handle;
190
116
    return strlen(buf);
191
117
}
192
118
 
193
 
SYSFS_SET_FUNCTION(pcidriver_store_kmem_free)
 
119
static SYSFS_SET_FUNCTION(pcidriver_store_kmem_free)
194
120
{
195
121
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
196
122
    unsigned int id;
209
135
    return strlen(buf);
210
136
}
211
137
 
212
 
SYSFS_GET_FUNCTION(pcidriver_show_kbuffers)
 
138
static SYSFS_GET_FUNCTION(pcidriver_show_kbuffers)
213
139
{
214
140
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
215
141
    int offset = 0;
238
164
    return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1);
239
165
}
240
166
 
241
 
SYSFS_GET_FUNCTION(pcidriver_show_umappings)
 
167
static SYSFS_GET_FUNCTION(pcidriver_show_umappings)
242
168
{
243
169
    int offset = 0;
244
170
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
268
194
    return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1);
269
195
}
270
196
 
271
 
SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap)
 
197
static SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap)
272
198
{
273
199
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
274
200
    pcidriver_umem_entry_t *umem_entry;
285
211
err:
286
212
    return strlen(buf);
287
213
}
 
214
 
 
215
static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry)
 
216
{
 
217
    pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
 
218
 
 
219
    /* As we can be sure that attr.name contains a filename which we
 
220
     * created (see _pcidriver_sysfs_initialize), we do not need to have
 
221
     * sanity checks but can directly call simple_strtol() */
 
222
    int id = simple_strtol(attr->attr.name + strlen("kbuf"), NULL, 10);
 
223
    pcidriver_kmem_entry_t *entry = pcidriver_kmem_find_entry_id(privdata, id);
 
224
    if (entry) {
 
225
        unsigned long addr = entry->cpua;
 
226
        unsigned long dma_addr = entry->dma_handle;
 
227
 
 
228
        if (entry->size >= 16) {
 
229
            pcidriver_kmem_sync_entry(privdata, entry, PCILIB_KMEM_SYNC_FROMDEVICE);
 
230
            return snprintf(buf, PAGE_SIZE, "buffer: %d\naddr: %lx\nhw addr: %llx\nbus addr: %lx\ntype: %lx\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\ndata: %8x %8x %8x %8x\n", id, addr, virt_to_phys((void*)addr), dma_addr, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode, *(u32*)(entry->cpua), *(u32*)(entry->cpua + 4),  *(u32*)(entry->cpua + 8), *(u32*)(entry->cpua + 12));
 
231
        } else
 
232
            return snprintf(buf, PAGE_SIZE, "buffer: %d\naddr: %lx\nhw addr: %llx\nbus addr: %lx\ntype: %lx\nuse: 0x%lx\nitem: %lu\nsize: %lu\nrefs: %lu\nhw ref: %i\nmode: 0x%lx\n", id, addr, virt_to_phys((void*)addr), dma_addr, entry->type, entry->use, entry->item, entry->size, entry->refs&KMEM_REF_COUNT, (entry->refs&KMEM_REF_HW)?1:0, entry->mode);
 
233
    } else
 
234
        return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id);
 
235
}
 
236
 
 
237
static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry)
 
238
{
 
239
    return 0;
 
240
}
 
241
 
 
242
 
 
243
#ifdef ENABLE_IRQ
 
244
static DEVICE_ATTR(irq_count, S_IRUGO, pcidriver_show_irq_count, NULL);
 
245
static DEVICE_ATTR(irq_queues, S_IRUGO, pcidriver_show_irq_queues, NULL);
 
246
#endif
 
247
 
 
248
static DEVICE_ATTR(mmap_mode, 0664, pcidriver_show_mmap_mode, pcidriver_store_mmap_mode);
 
249
static DEVICE_ATTR(mmap_area, 0664, pcidriver_show_mmap_area, pcidriver_store_mmap_area);
 
250
static DEVICE_ATTR(kmem_count, 0444, pcidriver_show_kmem_count, NULL);
 
251
static DEVICE_ATTR(kbuffers, 0444, pcidriver_show_kbuffers, NULL);
 
252
static DEVICE_ATTR(kmem_alloc, 0220, NULL, pcidriver_store_kmem_alloc);
 
253
static DEVICE_ATTR(kmem_free, 0220, NULL, pcidriver_store_kmem_free);
 
254
static DEVICE_ATTR(umappings, 0444, pcidriver_show_umappings, NULL);
 
255
static DEVICE_ATTR(umem_unmap, 0220, NULL, pcidriver_store_umem_unmap);
 
256
 
 
257
int pcidriver_create_sysfs_attributes(pcidriver_privdata_t *privdata) {
 
258
#ifdef ENABLE_IRQ
 
259
    SYSFS_ATTR_CREATE(irq_count);
 
260
    SYSFS_ATTR_CREATE(irq_queues);
 
261
#endif
 
262
 
 
263
    SYSFS_ATTR_CREATE(mmap_mode);
 
264
    SYSFS_ATTR_CREATE(mmap_area);
 
265
    SYSFS_ATTR_CREATE(kmem_count);
 
266
    SYSFS_ATTR_CREATE(kmem_alloc);
 
267
    SYSFS_ATTR_CREATE(kmem_free);
 
268
    SYSFS_ATTR_CREATE(kbuffers);
 
269
    SYSFS_ATTR_CREATE(umappings);
 
270
    SYSFS_ATTR_CREATE(umem_unmap);
 
271
 
 
272
    return 0;
 
273
}
 
274
 
 
275
void pcidriver_remove_sysfs_attributes(pcidriver_privdata_t *privdata) {
 
276
#ifdef ENABLE_IRQ
 
277
    SYSFS_ATTR_REMOVE(irq_count);
 
278
    SYSFS_ATTR_REMOVE(irq_queues);
 
279
#endif
 
280
 
 
281
    SYSFS_ATTR_REMOVE(mmap_mode);
 
282
    SYSFS_ATTR_REMOVE(mmap_area);
 
283
    SYSFS_ATTR_REMOVE(kmem_count);
 
284
    SYSFS_ATTR_REMOVE(kmem_alloc);
 
285
    SYSFS_ATTR_REMOVE(kmem_free);
 
286
    SYSFS_ATTR_REMOVE(kbuffers);
 
287
    SYSFS_ATTR_REMOVE(umappings);
 
288
    SYSFS_ATTR_REMOVE(umem_unmap);
 
289
}
 
290
 
 
291
/**
 
292
 *
 
293
 * Removes the file from sysfs and frees the allocated (kstrdup()) memory.
 
294
 *
 
295
 */
 
296
void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct device_attribute *sysfs_attr)
 
297
{
 
298
    device_remove_file(privdata->class_dev, sysfs_attr);
 
299
    kfree(sysfs_attr->attr.name);
 
300
}
 
301
 
 
302
/**
 
303
 *
 
304
 * Initializes the sysfs attributes for an kmem/umem-entry
 
305
 *
 
306
 */
 
307
static int _pcidriver_sysfs_initialize(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr, const char *fmtstring, SYSFS_GET_FUNCTION((*callback)))
 
308
{
 
309
    /* sysfs attributes for kmem buffers don’t make sense before 2.6.13, as
 
310
       we have no mmap support before */
 
311
    char namebuffer[16];
 
312
 
 
313
    /* allocate space for the name of the attribute */
 
314
    snprintf(namebuffer, sizeof(namebuffer), fmtstring, id);
 
315
 
 
316
    if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL)
 
317
        return -ENOMEM;
 
318
 
 
319
    sysfs_attr->attr.mode = S_IRUGO;
 
320
    sysfs_attr->show = callback;
 
321
    sysfs_attr->store = NULL;
 
322
 
 
323
    /* name and add attribute */
 
324
    if (device_create_file(privdata->class_dev, sysfs_attr) != 0)
 
325
        return -ENXIO; /* Device not configured. Not the really best choice, but hm. */
 
326
 
 
327
    return 0;
 
328
}
 
329
 
 
330
int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr)
 
331
{
 
332
    return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "kbuf%d", pcidriver_show_kmem_entry);
 
333
}
 
334
 
 
335
int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr)
 
336
{
 
337
    return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry);
 
338
}