0001
0002
0003
0004
0005
0006
0007 #include <linux/init.h>
0008 #include <linux/module.h>
0009 #include <linux/dmaengine.h>
0010 #include <linux/pci.h>
0011 #include "dma.h"
0012 #include "registers.h"
0013 #include "hw.h"
0014
0015 #include "../dmaengine.h"
0016
0017 static ssize_t cap_show(struct dma_chan *c, char *page)
0018 {
0019 struct dma_device *dma = c->device;
0020
0021 return sprintf(page, "copy%s%s%s%s%s\n",
0022 dma_has_cap(DMA_PQ, dma->cap_mask) ? " pq" : "",
0023 dma_has_cap(DMA_PQ_VAL, dma->cap_mask) ? " pq_val" : "",
0024 dma_has_cap(DMA_XOR, dma->cap_mask) ? " xor" : "",
0025 dma_has_cap(DMA_XOR_VAL, dma->cap_mask) ? " xor_val" : "",
0026 dma_has_cap(DMA_INTERRUPT, dma->cap_mask) ? " intr" : "");
0027
0028 }
0029 struct ioat_sysfs_entry ioat_cap_attr = __ATTR_RO(cap);
0030
0031 static ssize_t version_show(struct dma_chan *c, char *page)
0032 {
0033 struct dma_device *dma = c->device;
0034 struct ioatdma_device *ioat_dma = to_ioatdma_device(dma);
0035
0036 return sprintf(page, "%d.%d\n",
0037 ioat_dma->version >> 4, ioat_dma->version & 0xf);
0038 }
0039 struct ioat_sysfs_entry ioat_version_attr = __ATTR_RO(version);
0040
0041 static ssize_t
0042 ioat_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
0043 {
0044 struct ioat_sysfs_entry *entry;
0045 struct ioatdma_chan *ioat_chan;
0046
0047 entry = container_of(attr, struct ioat_sysfs_entry, attr);
0048 ioat_chan = container_of(kobj, struct ioatdma_chan, kobj);
0049
0050 if (!entry->show)
0051 return -EIO;
0052 return entry->show(&ioat_chan->dma_chan, page);
0053 }
0054
0055 static ssize_t
0056 ioat_attr_store(struct kobject *kobj, struct attribute *attr,
0057 const char *page, size_t count)
0058 {
0059 struct ioat_sysfs_entry *entry;
0060 struct ioatdma_chan *ioat_chan;
0061
0062 entry = container_of(attr, struct ioat_sysfs_entry, attr);
0063 ioat_chan = container_of(kobj, struct ioatdma_chan, kobj);
0064
0065 if (!entry->store)
0066 return -EIO;
0067 return entry->store(&ioat_chan->dma_chan, page, count);
0068 }
0069
0070 const struct sysfs_ops ioat_sysfs_ops = {
0071 .show = ioat_attr_show,
0072 .store = ioat_attr_store,
0073 };
0074
0075 void ioat_kobject_add(struct ioatdma_device *ioat_dma, struct kobj_type *type)
0076 {
0077 struct dma_device *dma = &ioat_dma->dma_dev;
0078 struct dma_chan *c;
0079
0080 list_for_each_entry(c, &dma->channels, device_node) {
0081 struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
0082 struct kobject *parent = &c->dev->device.kobj;
0083 int err;
0084
0085 err = kobject_init_and_add(&ioat_chan->kobj, type,
0086 parent, "quickdata");
0087 if (err) {
0088 dev_warn(to_dev(ioat_chan),
0089 "sysfs init error (%d), continuing...\n", err);
0090 kobject_put(&ioat_chan->kobj);
0091 set_bit(IOAT_KOBJ_INIT_FAIL, &ioat_chan->state);
0092 }
0093 }
0094 }
0095
0096 void ioat_kobject_del(struct ioatdma_device *ioat_dma)
0097 {
0098 struct dma_device *dma = &ioat_dma->dma_dev;
0099 struct dma_chan *c;
0100
0101 list_for_each_entry(c, &dma->channels, device_node) {
0102 struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
0103
0104 if (!test_bit(IOAT_KOBJ_INIT_FAIL, &ioat_chan->state)) {
0105 kobject_del(&ioat_chan->kobj);
0106 kobject_put(&ioat_chan->kobj);
0107 }
0108 }
0109 }
0110
0111 static ssize_t ring_size_show(struct dma_chan *c, char *page)
0112 {
0113 struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
0114
0115 return sprintf(page, "%d\n", (1 << ioat_chan->alloc_order) & ~1);
0116 }
0117 static struct ioat_sysfs_entry ring_size_attr = __ATTR_RO(ring_size);
0118
0119 static ssize_t ring_active_show(struct dma_chan *c, char *page)
0120 {
0121 struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
0122
0123
0124 return sprintf(page, "%d\n", ioat_ring_active(ioat_chan));
0125 }
0126 static struct ioat_sysfs_entry ring_active_attr = __ATTR_RO(ring_active);
0127
0128 static ssize_t intr_coalesce_show(struct dma_chan *c, char *page)
0129 {
0130 struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
0131
0132 return sprintf(page, "%d\n", ioat_chan->intr_coalesce);
0133 }
0134
0135 static ssize_t intr_coalesce_store(struct dma_chan *c, const char *page,
0136 size_t count)
0137 {
0138 int intr_coalesce = 0;
0139 struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
0140
0141 if (sscanf(page, "%du", &intr_coalesce) != -1) {
0142 if ((intr_coalesce < 0) ||
0143 (intr_coalesce > IOAT_INTRDELAY_MASK))
0144 return -EINVAL;
0145 ioat_chan->intr_coalesce = intr_coalesce;
0146 }
0147
0148 return count;
0149 }
0150
0151 static struct ioat_sysfs_entry intr_coalesce_attr = __ATTR_RW(intr_coalesce);
0152
0153 static struct attribute *ioat_attrs[] = {
0154 &ring_size_attr.attr,
0155 &ring_active_attr.attr,
0156 &ioat_cap_attr.attr,
0157 &ioat_version_attr.attr,
0158 &intr_coalesce_attr.attr,
0159 NULL,
0160 };
0161 ATTRIBUTE_GROUPS(ioat);
0162
0163 struct kobj_type ioat_ktype = {
0164 .sysfs_ops = &ioat_sysfs_ops,
0165 .default_groups = ioat_groups,
0166 };