diff options
Diffstat (limited to 'driver/sysfs.c')
-rw-r--r-- | driver/sysfs.c | 293 |
1 files changed, 136 insertions, 157 deletions
diff --git a/driver/sysfs.c b/driver/sysfs.c index abc1c8a..19865fc 100644 --- a/driver/sysfs.c +++ b/driver/sysfs.c @@ -35,46 +35,40 @@ static SYSFS_GET_FUNCTION(pcidriver_show_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))) + 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 */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) - char namebuffer[16]; + /* 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); + /* 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; + if ((sysfs_attr->attr.name = kstrdup(namebuffer, GFP_KERNEL)) == NULL) + return -ENOMEM; - sysfs_attr->attr.mode = S_IRUGO; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) - // DS: Shall we lock now while accessing driver data structures??? - sysfs_attr->attr.owner = THIS_MODULE; -#endif - sysfs_attr->show = callback; - sysfs_attr->store = NULL; - - /* 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. */ -#endif + sysfs_attr->attr.mode = S_IRUGO; + sysfs_attr->show = callback; + sysfs_attr->store = NULL; - return 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); + 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); + return _pcidriver_sysfs_initialize(privdata, id, sysfs_attr, "umem%d", pcidriver_show_umem_entry); } /** @@ -84,225 +78,210 @@ int pcidriver_sysfs_initialize_umem(pcidriver_privdata_t *privdata, int id, stru */ void pcidriver_sysfs_remove(pcidriver_privdata_t *privdata, struct class_device_attribute *sysfs_attr) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) - class_device_remove_file(privdata->class_dev, sysfs_attr); - kfree(sysfs_attr->attr.name); -#endif + class_device_remove_file(privdata->class_dev, sysfs_attr); + kfree(sysfs_attr->attr.name); } static SYSFS_GET_FUNCTION(pcidriver_show_kmem_entry) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) - 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); -#else - return 0; -#endif + 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) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13) -#if 0 - pcidriver_privdata_t *privdata = (pcidriver_privdata_t *)cls->class_data; - - return snprintf(buf, PAGE_SIZE, "I am in the umem_entry show function, class_device_kobj_name: %s\n", cls->kobj.name); -#endif - return 0; -#else - return 0; -#endif + return 0; } #ifdef ENABLE_IRQ SYSFS_GET_FUNCTION(pcidriver_show_irq_count) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - return snprintf(buf, PAGE_SIZE, "%d\n", privdata->irq_count); + return snprintf(buf, PAGE_SIZE, "%d\n", privdata->irq_count); } SYSFS_GET_FUNCTION(pcidriver_show_irq_queues) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - int i, offset; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + int i, offset; - /* output will be truncated to PAGE_SIZE */ - offset = snprintf(buf, PAGE_SIZE, "Queue\tOutstanding IRQs\n"); - for (i = 0; i < PCIDRIVER_INT_MAXSOURCES; i++) - offset += snprintf(buf+offset, PAGE_SIZE-offset, "%d\t%d\n", i, atomic_read(&(privdata->irq_outstanding[i])) ); + /* output will be truncated to PAGE_SIZE */ + offset = snprintf(buf, PAGE_SIZE, "Queue\tOutstanding IRQs\n"); + for (i = 0; i < PCIDRIVER_INT_MAXSOURCES; i++) + offset += snprintf(buf+offset, PAGE_SIZE-offset, "%d\t%d\n", i, atomic_read(&(privdata->irq_outstanding[i])) ); - return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); + return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); } #endif SYSFS_GET_FUNCTION(pcidriver_show_mmap_mode) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_mode); + return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_mode); } SYSFS_SET_FUNCTION(pcidriver_store_mmap_mode) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - int mode = -1; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + int mode = -1; - /* Set the mmap-mode if it is either PCIDRIVER_MMAP_PCI or PCIDRIVER_MMAP_KMEM */ - if (sscanf(buf, "%d", &mode) == 1 && - (mode == PCIDRIVER_MMAP_PCI || mode == PCIDRIVER_MMAP_KMEM)) - privdata->mmap_mode = mode; + /* Set the mmap-mode if it is either PCIDRIVER_MMAP_PCI or PCIDRIVER_MMAP_KMEM */ + if (sscanf(buf, "%d", &mode) == 1 && + (mode == PCIDRIVER_MMAP_PCI || mode == PCIDRIVER_MMAP_KMEM)) + privdata->mmap_mode = mode; - return strlen(buf); + return strlen(buf); } SYSFS_GET_FUNCTION(pcidriver_show_mmap_area) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_area); + return snprintf(buf, PAGE_SIZE, "%d\n", privdata->mmap_area); } SYSFS_SET_FUNCTION(pcidriver_store_mmap_area) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - int temp = -1; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + int temp = -1; - sscanf(buf, "%d", &temp); + sscanf(buf, "%d", &temp); - if ((temp >= PCIDRIVER_BAR0) && (temp <= PCIDRIVER_BAR5)) - privdata->mmap_area = temp; + if ((temp >= PCIDRIVER_BAR0) && (temp <= PCIDRIVER_BAR5)) + privdata->mmap_area = temp; - return strlen(buf); + return strlen(buf); } SYSFS_GET_FUNCTION(pcidriver_show_kmem_count) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&(privdata->kmem_count))); + return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&(privdata->kmem_count))); } SYSFS_SET_FUNCTION(pcidriver_store_kmem_alloc) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - kmem_handle_t kmem_handle; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + kmem_handle_t kmem_handle; - /* FIXME: guillermo: is validation of parsing an unsigned int enough? */ - if (sscanf(buf, "%lu", &kmem_handle.size) == 1) - pcidriver_kmem_alloc(privdata, &kmem_handle); + /* FIXME: guillermo: is validation of parsing an unsigned int enough? */ + if (sscanf(buf, "%lu", &kmem_handle.size) == 1) + pcidriver_kmem_alloc(privdata, &kmem_handle); - return strlen(buf); + return strlen(buf); } SYSFS_SET_FUNCTION(pcidriver_store_kmem_free) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - unsigned int id; - pcidriver_kmem_entry_t *kmem_entry; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + unsigned int id; + pcidriver_kmem_entry_t *kmem_entry; - /* Parse the ID of the kernel memory to be freed, check bounds */ - if (sscanf(buf, "%u", &id) != 1 || - (id >= atomic_read(&(privdata->kmem_count)))) - goto err; + /* Parse the ID of the kernel memory to be freed, check bounds */ + if (sscanf(buf, "%u", &id) != 1 || + (id >= atomic_read(&(privdata->kmem_count)))) + goto err; - if ((kmem_entry = pcidriver_kmem_find_entry_id(privdata,id)) == NULL) - goto err; + if ((kmem_entry = pcidriver_kmem_find_entry_id(privdata,id)) == NULL) + goto err; - pcidriver_kmem_free_entry(privdata, kmem_entry ); + pcidriver_kmem_free_entry(privdata, kmem_entry ); err: - return strlen(buf); + return strlen(buf); } SYSFS_GET_FUNCTION(pcidriver_show_kbuffers) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - int offset = 0; - struct list_head *ptr; - pcidriver_kmem_entry_t *entry; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + int offset = 0; + struct list_head *ptr; + pcidriver_kmem_entry_t *entry; - /* print the header */ - offset += snprintf(buf, PAGE_SIZE, "kbuf#\tcpu addr\tsize\n"); + /* print the header */ + offset += snprintf(buf, PAGE_SIZE, "kbuf#\tcpu addr\tsize\n"); - spin_lock(&(privdata->kmemlist_lock)); - list_for_each(ptr, &(privdata->kmem_list)) { - entry = list_entry(ptr, pcidriver_kmem_entry_t, list); + spin_lock(&(privdata->kmemlist_lock)); + list_for_each(ptr, &(privdata->kmem_list)) { + entry = list_entry(ptr, pcidriver_kmem_entry_t, list); - /* print entry info */ - if (offset > PAGE_SIZE) { - spin_unlock( &(privdata->kmemlist_lock) ); - return PAGE_SIZE; - } + /* print entry info */ + if (offset > PAGE_SIZE) { + spin_unlock( &(privdata->kmemlist_lock) ); + return PAGE_SIZE; + } - offset += snprintf(buf+offset, PAGE_SIZE-offset, "%3d\t%08lx\t%lu\n", entry->id, (unsigned long)(entry->dma_handle), entry->size ); - } + offset += snprintf(buf+offset, PAGE_SIZE-offset, "%3d\t%08lx\t%lu\n", entry->id, (unsigned long)(entry->dma_handle), entry->size ); + } - spin_unlock(&(privdata->kmemlist_lock)); + spin_unlock(&(privdata->kmemlist_lock)); - /* output will be truncated to PAGE_SIZE */ - return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); + /* output will be truncated to PAGE_SIZE */ + return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); } SYSFS_GET_FUNCTION(pcidriver_show_umappings) { - int offset = 0; - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - struct list_head *ptr; - pcidriver_umem_entry_t *entry; + int offset = 0; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + struct list_head *ptr; + pcidriver_umem_entry_t *entry; - /* print the header */ - offset += snprintf(buf, PAGE_SIZE, "umap#\tn_pages\tsg_ents\n"); + /* print the header */ + offset += snprintf(buf, PAGE_SIZE, "umap#\tn_pages\tsg_ents\n"); - spin_lock( &(privdata->umemlist_lock) ); - list_for_each( ptr, &(privdata->umem_list) ) { - entry = list_entry(ptr, pcidriver_umem_entry_t, list ); + spin_lock( &(privdata->umemlist_lock) ); + list_for_each( ptr, &(privdata->umem_list) ) { + entry = list_entry(ptr, pcidriver_umem_entry_t, list ); - /* print entry info */ - if (offset > PAGE_SIZE) { - spin_unlock( &(privdata->umemlist_lock) ); - return PAGE_SIZE; - } + /* print entry info */ + if (offset > PAGE_SIZE) { + spin_unlock( &(privdata->umemlist_lock) ); + return PAGE_SIZE; + } - offset += snprintf(buf+offset, PAGE_SIZE-offset, "%3d\t%lu\t%lu\n", entry->id, - (unsigned long)(entry->nr_pages), (unsigned long)(entry->nents)); - } + offset += snprintf(buf+offset, PAGE_SIZE-offset, "%3d\t%lu\t%lu\n", entry->id, + (unsigned long)(entry->nr_pages), (unsigned long)(entry->nents)); + } - spin_unlock( &(privdata->umemlist_lock) ); + spin_unlock( &(privdata->umemlist_lock) ); - /* output will be truncated to PAGE_SIZE */ - return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); + /* output will be truncated to PAGE_SIZE */ + return (offset > PAGE_SIZE ? PAGE_SIZE : offset+1); } SYSFS_SET_FUNCTION(pcidriver_store_umem_unmap) { - pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; - pcidriver_umem_entry_t *umem_entry; - unsigned int id; + pcidriver_privdata_t *privdata = SYSFS_GET_PRIVDATA; + pcidriver_umem_entry_t *umem_entry; + unsigned int id; - if (sscanf(buf, "%u", &id) != 1 || - (id >= atomic_read(&(privdata->umem_count)))) - goto err; + if (sscanf(buf, "%u", &id) != 1 || + (id >= atomic_read(&(privdata->umem_count)))) + goto err; - if ((umem_entry = pcidriver_umem_find_entry_id(privdata, id)) == NULL) - goto err; + if ((umem_entry = pcidriver_umem_find_entry_id(privdata, id)) == NULL) + goto err; - pcidriver_umem_sgunmap(privdata, umem_entry); + pcidriver_umem_sgunmap(privdata, umem_entry); err: - return strlen(buf); + return strlen(buf); } |