1 /* 2 * Intel I/OAT DMA Linux driver 3 * Copyright(c) 2004 - 2015 Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * The full GNU General Public License is included in this distribution in 15 * the file called "COPYING". 16 * 17 */ 18 19 #include <linux/init.h> 20 #include <linux/module.h> 21 #include <linux/dmaengine.h> 22 #include <linux/pci.h> 23 #include "dma.h" 24 #include "registers.h" 25 #include "hw.h" 26 27 #include "../dmaengine.h" 28 29 static ssize_t cap_show(struct dma_chan *c, char *page) 30 { 31 struct dma_device *dma = c->device; 32 33 return sprintf(page, "copy%s%s%s%s%s\n", 34 dma_has_cap(DMA_PQ, dma->cap_mask) ? " pq" : "", 35 dma_has_cap(DMA_PQ_VAL, dma->cap_mask) ? " pq_val" : "", 36 dma_has_cap(DMA_XOR, dma->cap_mask) ? " xor" : "", 37 dma_has_cap(DMA_XOR_VAL, dma->cap_mask) ? " xor_val" : "", 38 dma_has_cap(DMA_INTERRUPT, dma->cap_mask) ? " intr" : ""); 39 40 } 41 struct ioat_sysfs_entry ioat_cap_attr = __ATTR_RO(cap); 42 43 static ssize_t version_show(struct dma_chan *c, char *page) 44 { 45 struct dma_device *dma = c->device; 46 struct ioatdma_device *ioat_dma = to_ioatdma_device(dma); 47 48 return sprintf(page, "%d.%d\n", 49 ioat_dma->version >> 4, ioat_dma->version & 0xf); 50 } 51 struct ioat_sysfs_entry ioat_version_attr = __ATTR_RO(version); 52 53 static ssize_t 54 ioat_attr_show(struct kobject *kobj, struct attribute *attr, char *page) 55 { 56 struct ioat_sysfs_entry *entry; 57 struct ioatdma_chan *ioat_chan; 58 59 entry = container_of(attr, struct ioat_sysfs_entry, attr); 60 ioat_chan = container_of(kobj, struct ioatdma_chan, kobj); 61 62 if (!entry->show) 63 return -EIO; 64 return entry->show(&ioat_chan->dma_chan, page); 65 } 66 67 const struct sysfs_ops ioat_sysfs_ops = { 68 .show = ioat_attr_show, 69 }; 70 71 void ioat_kobject_add(struct ioatdma_device *ioat_dma, struct kobj_type *type) 72 { 73 struct dma_device *dma = &ioat_dma->dma_dev; 74 struct dma_chan *c; 75 76 list_for_each_entry(c, &dma->channels, device_node) { 77 struct ioatdma_chan *ioat_chan = to_ioat_chan(c); 78 struct kobject *parent = &c->dev->device.kobj; 79 int err; 80 81 err = kobject_init_and_add(&ioat_chan->kobj, type, 82 parent, "quickdata"); 83 if (err) { 84 dev_warn(to_dev(ioat_chan), 85 "sysfs init error (%d), continuing...\n", err); 86 kobject_put(&ioat_chan->kobj); 87 set_bit(IOAT_KOBJ_INIT_FAIL, &ioat_chan->state); 88 } 89 } 90 } 91 92 void ioat_kobject_del(struct ioatdma_device *ioat_dma) 93 { 94 struct dma_device *dma = &ioat_dma->dma_dev; 95 struct dma_chan *c; 96 97 list_for_each_entry(c, &dma->channels, device_node) { 98 struct ioatdma_chan *ioat_chan = to_ioat_chan(c); 99 100 if (!test_bit(IOAT_KOBJ_INIT_FAIL, &ioat_chan->state)) { 101 kobject_del(&ioat_chan->kobj); 102 kobject_put(&ioat_chan->kobj); 103 } 104 } 105 } 106 107 static ssize_t ring_size_show(struct dma_chan *c, char *page) 108 { 109 struct ioatdma_chan *ioat_chan = to_ioat_chan(c); 110 111 return sprintf(page, "%d\n", (1 << ioat_chan->alloc_order) & ~1); 112 } 113 static struct ioat_sysfs_entry ring_size_attr = __ATTR_RO(ring_size); 114 115 static ssize_t ring_active_show(struct dma_chan *c, char *page) 116 { 117 struct ioatdma_chan *ioat_chan = to_ioat_chan(c); 118 119 /* ...taken outside the lock, no need to be precise */ 120 return sprintf(page, "%d\n", ioat_ring_active(ioat_chan)); 121 } 122 static struct ioat_sysfs_entry ring_active_attr = __ATTR_RO(ring_active); 123 124 static struct attribute *ioat_attrs[] = { 125 &ring_size_attr.attr, 126 &ring_active_attr.attr, 127 &ioat_cap_attr.attr, 128 &ioat_version_attr.attr, 129 NULL, 130 }; 131 132 struct kobj_type ioat_ktype = { 133 .sysfs_ops = &ioat_sysfs_ops, 134 .default_attrs = ioat_attrs, 135 }; 136