18
18
#include <linux/pagemap.h>
19
19
#include <linux/kernel.h>
23
#include "pciDriver.h"
29
static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry);
30
static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry);
34
* Initializes the sysfs attributes for an kmem/umem-entry
37
static int _pcidriver_sysfs_initialize(pcidriver_privdata_t *privdata,
39
struct class_device_attribute *sysfs_attr,
40
const char *fmtstring,
41
SYSFS_GET_FUNCTION((*callback)))
43
/* sysfs attributes for kmem buffers don’t make sense before 2.6.13, as
44
we have no mmap support before */
47
/* allocate space for the name of the attribute */
48
snprintf(namebuffer, sizeof(namebuffer), fmtstring, id);
50
if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL)
53
sysfs_attr->attr.mode = S_IRUGO;
54
sysfs_attr->show = callback;
55
sysfs_attr->store = NULL;
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. */
64
int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr)
66
return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "kbuf%d", pcidriver_show_kmem_entry);
69
int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr)
71
return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry);
76
* Removes the file from sysfs and frees the allocated (kstrdup()) memory.
79
void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct class_device_attribute *sysfs_attr)
81
class_device_remove_file(privdata->class_dev, sysfs_attr);
82
kfree(sysfs_attr->attr.name);
85
static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry)
87
pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
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);
95
unsigned long addr = entry->cpua;
96
unsigned long dma_addr = entry->dma_handle;
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));
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);
104
return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id);
107
static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry)
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)
27
#define SYSFS_ATTR_NAME(name) (dev_attr_##name)
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; \
34
#define SYSFS_ATTR_REMOVE(name) do { \
35
device_remove_file(privdata->class_dev, &SYSFS_ATTR_NAME(name)); \
113
SYSFS_GET_FUNCTION(pcidriver_show_irq_count)
39
static SYSFS_GET_FUNCTION(pcidriver_show_irq_count)
115
41
pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
117
43
return snprintf(buf, PAGE_SIZE, "%d\n", privdata->irq_count);
120
SYSFS_GET_FUNCTION(pcidriver_show_irq_queues)
46
static SYSFS_GET_FUNCTION(pcidriver_show_irq_queues)
122
48
pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
286
212
return strlen(buf);
215
static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry)
217
pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA;
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);
225
unsigned long addr = entry->cpua;
226
unsigned long dma_addr = entry->dma_handle;
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));
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);
234
return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id);
237
static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry)
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);
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);
257
int pcidriver_create_sysfs_attributes(pcidriver_privdata_t *privdata) {
259
SYSFS_ATTR_CREATE(irq_count);
260
SYSFS_ATTR_CREATE(irq_queues);
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);
275
void pcidriver_remove_sysfs_attributes(pcidriver_privdata_t *privdata) {
277
SYSFS_ATTR_REMOVE(irq_count);
278
SYSFS_ATTR_REMOVE(irq_queues);
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);
293
* Removes the file from sysfs and frees the allocated (kstrdup()) memory.
296
void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct device_attribute *sysfs_attr)
298
device_remove_file(privdata->class_dev, sysfs_attr);
299
kfree(sysfs_attr->attr.name);
304
* Initializes the sysfs attributes for an kmem/umem-entry
307
static int _pcidriver_sysfs_initialize(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr, const char *fmtstring, SYSFS_GET_FUNCTION((*callback)))
309
/* sysfs attributes for kmem buffers don’t make sense before 2.6.13, as
310
we have no mmap support before */
313
/* allocate space for the name of the attribute */
314
snprintf(namebuffer, sizeof(namebuffer), fmtstring, id);
316
if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL)
319
sysfs_attr->attr.mode = S_IRUGO;
320
sysfs_attr->show = callback;
321
sysfs_attr->store = NULL;
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. */
330
int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr)
332
return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "kbuf%d", pcidriver_show_kmem_entry);
335
int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr)
337
return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry);