diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2016-03-02 19:37:30 +0100 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2016-03-02 19:37:30 +0100 |
commit | 1120e8745ccd3e512fe2016c9e5092fcd378490a (patch) | |
tree | 0e89ac6cd82c213a78d79d10d3fecff06f21127d /driver/sysfs.c | |
parent | 01e857cca352e73243d00b62a0c248a35cea6b71 (diff) | |
download | pcitool-1120e8745ccd3e512fe2016c9e5092fcd378490a.tar.gz pcitool-1120e8745ccd3e512fe2016c9e5092fcd378490a.tar.bz2 pcitool-1120e8745ccd3e512fe2016c9e5092fcd378490a.tar.xz pcitool-1120e8745ccd3e512fe2016c9e5092fcd378490a.zip |
Restructure driver headers
Diffstat (limited to 'driver/sysfs.c')
-rw-r--r-- | driver/sysfs.c | 247 |
1 files changed, 149 insertions, 98 deletions
diff --git a/driver/sysfs.c b/driver/sysfs.c index 19865fc..d0fd870 100644 --- a/driver/sysfs.c +++ b/driver/sysfs.c @@ -18,106 +18,32 @@ #include <linux/pagemap.h> #include <linux/kernel.h> -#include "compat.h" -#include "config.h" -#include "pciDriver.h" -#include "common.h" -#include "umem.h" -#include "kmem.h" -#include "sysfs.h" +#include "base.h" -static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry); -static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry); +#define SYSFS_GET_PRIVDATA dev_get_drvdata(dev) +#define SYSFS_GET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, char *buf) +#define SYSFS_SET_FUNCTION(name) ssize_t name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -/** - * - * Initializes the sysfs attributes for an kmem/umem-entry - * - */ -static int _pcidriver_sysfs_initialize(pcidriver_privdata_t *privdata, - int id, - struct class_device_attribute *sysfs_attr, - const char *fmtstring, - SYSFS_GET_FUNCTION((*callback))) -{ - /* sysfs attributes for kmem buffers don’t make sense before 2.6.13, as - we have no mmap support before */ - char namebuffer[16]; - - /* allocate space for the name of the attribute */ - snprintf(namebuffer, sizeof(namebuffer), fmtstring, id); - - if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL) - return -ENOMEM; +#define SYSFS_ATTR_NAME(name) (dev_attr_##name) - sysfs_attr->attr.mode = S_IRUGO; - sysfs_attr->show = callback; - sysfs_attr->store = NULL; +#define SYSFS_ATTR_CREATE(name) do { \ + int err = device_create_file(privdata->class_dev, &SYSFS_ATTR_NAME(name)); \ + if (err != 0) return err; \ + } while (0) - /* name and add attribute */ - if (class_device_create_file(privdata->class_dev, sysfs_attr) != 0) - return -ENXIO; /* Device not configured. Not the really best choice, but hm. */ - - return 0; -} - -int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr) -{ - return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "kbuf%d", pcidriver_show_kmem_entry); -} - -int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct class_device_attribute *sysfs_attr) -{ - return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry); -} - -/** - * - * Removes the file from sysfs and frees the allocated (kstrdup()) memory. - * - */ -void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct class_device_attribute *sysfs_attr) -{ - class_device_remove_file(privdata->class_dev, sysfs_attr); - kfree(sysfs_attr->attr.name); -} - -static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry) -{ - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - - /* As we can be sure that attr.name contains a filename which we - * created (see _pcidriver_sysfs_initialize), we do not need to have - * sanity checks but can directly call simple_strtol() */ - int id = simple_strtol(attr->attr.name + strlen("kbuf"), NULL, 10); - pcidriver_kmem_entry_t *entry = pcidriver_kmem_find_entry_id(privdata, id); - if (entry) { - unsigned long addr = entry->cpua; - unsigned long dma_addr = entry->dma_handle; - - if (entry->size >= 16) { - pcidriver_kmem_sync_entry(privdata, entry, PCILIB_KMEM_SYNC_FROMDEVICE); - 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)); - } else - 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); - } else - return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id); -} - -static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry) -{ - return 0; -} +#define SYSFS_ATTR_REMOVE(name) do { \ + device_remove_file(privdata->class_dev, &SYSFS_ATTR_NAME(name)); \ + } while (0) #ifdef ENABLE_IRQ -SYSFS_GET_FUNCTION(pcidriver_show_irq_count) +static SYSFS_GET_FUNCTION(pcidriver_show_irq_count) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; return snprintf(buf, PAGE_SIZE, "%d\n", privdata->irq_count); } -SYSFS_GET_FUNCTION(pcidriver_show_irq_queues) +static SYSFS_GET_FUNCTION(pcidriver_show_irq_queues) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; int i, offset; @@ -131,14 +57,14 @@ SYSFS_GET_FUNCTION(pcidriver_show_irq_queues) } #endif -SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode) +static SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_mode); } -SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode) +static SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; int mode = -1; @@ -151,14 +77,14 @@ SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode) return strlen(buf); } -SYSFS_GET_FUNCTION(pcidriver_show_mmap_area) +static SYSFS_GET_FUNCTION(pcidriver_show_mmap_area) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_area); } -SYSFS_SET_FUNCTION(pcidriver_store_mmap_area) +static SYSFS_SET_FUNCTION(pcidriver_store_mmap_area) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; int temp = -1; @@ -171,14 +97,14 @@ SYSFS_SET_FUNCTION(pcidriver_store_mmap_area) return strlen(buf); } -SYSFS_GET_FUNCTION(pcidriver_show_kmem_count) +static SYSFS_GET_FUNCTION(pcidriver_show_kmem_count) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&(privdata->kmem_count))); } -SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc) +static SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; kmem_handle_t kmem_handle; @@ -190,7 +116,7 @@ SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc) return strlen(buf); } -SYSFS_SET_FUNCTION(pcidriver_store_kmem_free) +static SYSFS_SET_FUNCTION(pcidriver_store_kmem_free) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; unsigned int id; @@ -209,7 +135,7 @@ err: return strlen(buf); } -SYSFS_GET_FUNCTION(pcidriver_show_kbuffers) +static SYSFS_GET_FUNCTION(pcidriver_show_kbuffers) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; int offset = 0; @@ -238,7 +164,7 @@ SYSFS_GET_FUNCTION(pcidriver_show_kbuffers) return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); } -SYSFS_GET_FUNCTION(pcidriver_show_umappings) +static SYSFS_GET_FUNCTION(pcidriver_show_umappings) { int offset = 0; pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; @@ -268,7 +194,7 @@ SYSFS_GET_FUNCTION(pcidriver_show_umappings) return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); } -SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap) +static SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap) { pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; pcidriver_umem_entry_t *umem_entry; @@ -285,3 +211,128 @@ SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap) err: return strlen(buf); } + +static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry) +{ + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + + /* As we can be sure that attr.name contains a filename which we + * created (see _pcidriver_sysfs_initialize), we do not need to have + * sanity checks but can directly call simple_strtol() */ + int id = simple_strtol(attr->attr.name + strlen("kbuf"), NULL, 10); + pcidriver_kmem_entry_t *entry = pcidriver_kmem_find_entry_id(privdata, id); + if (entry) { + unsigned long addr = entry->cpua; + unsigned long dma_addr = entry->dma_handle; + + if (entry->size >= 16) { + pcidriver_kmem_sync_entry(privdata, entry, PCILIB_KMEM_SYNC_FROMDEVICE); + 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)); + } else + 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); + } else + return snprintf(buf, PAGE_SIZE, "I am in the kmem_entry show function for buffer %d\n", id); +} + +static SYSFS_GET_FUNCTION(pcidriver_show_umem_entry) +{ + return 0; +} + + +#ifdef ENABLE_IRQ +static DEVICE_ATTR(irq_count, S_IRUGO, pcidriver_show_irq_count, NULL); +static DEVICE_ATTR(irq_queues, S_IRUGO, pcidriver_show_irq_queues, NULL); +#endif + +static DEVICE_ATTR(mmap_mode, 0664, pcidriver_show_mmap_mode, pcidriver_store_mmap_mode); +static DEVICE_ATTR(mmap_area, 0664, pcidriver_show_mmap_area, pcidriver_store_mmap_area); +static DEVICE_ATTR(kmem_count, 0444, pcidriver_show_kmem_count, NULL); +static DEVICE_ATTR(kbuffers, 0444, pcidriver_show_kbuffers, NULL); +static DEVICE_ATTR(kmem_alloc, 0220, NULL, pcidriver_store_kmem_alloc); +static DEVICE_ATTR(kmem_free, 0220, NULL, pcidriver_store_kmem_free); +static DEVICE_ATTR(umappings, 0444, pcidriver_show_umappings, NULL); +static DEVICE_ATTR(umem_unmap, 0220, NULL, pcidriver_store_umem_unmap); + +int pcidriver_create_sysfs_attributes(pcidriver_privdata_t *privdata) { +#ifdef ENABLE_IRQ + SYSFS_ATTR_CREATE(irq_count); + SYSFS_ATTR_CREATE(irq_queues); +#endif + + SYSFS_ATTR_CREATE(mmap_mode); + SYSFS_ATTR_CREATE(mmap_area); + SYSFS_ATTR_CREATE(kmem_count); + SYSFS_ATTR_CREATE(kmem_alloc); + SYSFS_ATTR_CREATE(kmem_free); + SYSFS_ATTR_CREATE(kbuffers); + SYSFS_ATTR_CREATE(umappings); + SYSFS_ATTR_CREATE(umem_unmap); + + return 0; +} + +void pcidriver_remove_sysfs_attributes(pcidriver_privdata_t *privdata) { +#ifdef ENABLE_IRQ + SYSFS_ATTR_REMOVE(irq_count); + SYSFS_ATTR_REMOVE(irq_queues); +#endif + + SYSFS_ATTR_REMOVE(mmap_mode); + SYSFS_ATTR_REMOVE(mmap_area); + SYSFS_ATTR_REMOVE(kmem_count); + SYSFS_ATTR_REMOVE(kmem_alloc); + SYSFS_ATTR_REMOVE(kmem_free); + SYSFS_ATTR_REMOVE(kbuffers); + SYSFS_ATTR_REMOVE(umappings); + SYSFS_ATTR_REMOVE(umem_unmap); +} + +/** + * + * Removes the file from sysfs and frees the allocated (kstrdup()) memory. + * + */ +void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct device_attribute *sysfs_attr) +{ + device_remove_file(privdata->class_dev, sysfs_attr); + kfree(sysfs_attr->attr.name); +} + +/** + * + * Initializes the sysfs attributes for an kmem/umem-entry + * + */ +static int _pcidriver_sysfs_initialize(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr, const char *fmtstring, SYSFS_GET_FUNCTION((*callback))) +{ + /* sysfs attributes for kmem buffers don’t make sense before 2.6.13, as + we have no mmap support before */ + char namebuffer[16]; + + /* allocate space for the name of the attribute */ + snprintf(namebuffer, sizeof(namebuffer), fmtstring, id); + + if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL) + return -ENOMEM; + + sysfs_attr->attr.mode = S_IRUGO; + sysfs_attr->show = callback; + sysfs_attr->store = NULL; + + /* name and add attribute */ + if (device_create_file(privdata->class_dev, sysfs_attr) != 0) + return -ENXIO; /* Device not configured. Not the really best choice, but hm. */ + + return 0; +} + +int pcidriver_sysfs_initialize_kmem(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr) +{ + return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "kbuf%d", pcidriver_show_kmem_entry); +} + +int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, struct device_attribute *sysfs_attr) +{ + return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry); +} |