aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c152
1 files changed, 113 insertions, 39 deletions
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 9bbf491d5d9e..2851bf831fb2 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -49,29 +49,57 @@ static DEFINE_MUTEX(dev_mutex);
49 49
50static struct dentry *c4iw_debugfs_root; 50static struct dentry *c4iw_debugfs_root;
51 51
52struct debugfs_qp_data { 52struct c4iw_debugfs_data {
53 struct c4iw_dev *devp; 53 struct c4iw_dev *devp;
54 char *buf; 54 char *buf;
55 int bufsize; 55 int bufsize;
56 int pos; 56 int pos;
57}; 57};
58 58
59static int count_qps(int id, void *p, void *data) 59static int count_idrs(int id, void *p, void *data)
60{ 60{
61 struct c4iw_qp *qp = p;
62 int *countp = data; 61 int *countp = data;
63 62
64 if (id != qp->wq.sq.qid)
65 return 0;
66
67 *countp = *countp + 1; 63 *countp = *countp + 1;
68 return 0; 64 return 0;
69} 65}
70 66
71static int dump_qps(int id, void *p, void *data) 67static ssize_t debugfs_read(struct file *file, char __user *buf, size_t count,
68 loff_t *ppos)
69{
70 struct c4iw_debugfs_data *d = file->private_data;
71 loff_t pos = *ppos;
72 loff_t avail = d->pos;
73
74 if (pos < 0)
75 return -EINVAL;
76 if (pos >= avail)
77 return 0;
78 if (count > avail - pos)
79 count = avail - pos;
80
81 while (count) {
82 size_t len = 0;
83
84 len = min((int)count, (int)d->pos - (int)pos);
85 if (copy_to_user(buf, d->buf + pos, len))
86 return -EFAULT;
87 if (len == 0)
88 return -EINVAL;
89
90 buf += len;
91 pos += len;
92 count -= len;
93 }
94 count = pos - *ppos;
95 *ppos = pos;
96 return count;
97}
98
99static int dump_qp(int id, void *p, void *data)
72{ 100{
73 struct c4iw_qp *qp = p; 101 struct c4iw_qp *qp = p;
74 struct debugfs_qp_data *qpd = data; 102 struct c4iw_debugfs_data *qpd = data;
75 int space; 103 int space;
76 int cc; 104 int cc;
77 105
@@ -101,7 +129,7 @@ static int dump_qps(int id, void *p, void *data)
101 129
102static int qp_release(struct inode *inode, struct file *file) 130static int qp_release(struct inode *inode, struct file *file)
103{ 131{
104 struct debugfs_qp_data *qpd = file->private_data; 132 struct c4iw_debugfs_data *qpd = file->private_data;
105 if (!qpd) { 133 if (!qpd) {
106 printk(KERN_INFO "%s null qpd?\n", __func__); 134 printk(KERN_INFO "%s null qpd?\n", __func__);
107 return 0; 135 return 0;
@@ -113,7 +141,7 @@ static int qp_release(struct inode *inode, struct file *file)
113 141
114static int qp_open(struct inode *inode, struct file *file) 142static int qp_open(struct inode *inode, struct file *file)
115{ 143{
116 struct debugfs_qp_data *qpd; 144 struct c4iw_debugfs_data *qpd;
117 int ret = 0; 145 int ret = 0;
118 int count = 1; 146 int count = 1;
119 147
@@ -126,7 +154,7 @@ static int qp_open(struct inode *inode, struct file *file)
126 qpd->pos = 0; 154 qpd->pos = 0;
127 155
128 spin_lock_irq(&qpd->devp->lock); 156 spin_lock_irq(&qpd->devp->lock);
129 idr_for_each(&qpd->devp->qpidr, count_qps, &count); 157 idr_for_each(&qpd->devp->qpidr, count_idrs, &count);
130 spin_unlock_irq(&qpd->devp->lock); 158 spin_unlock_irq(&qpd->devp->lock);
131 159
132 qpd->bufsize = count * 128; 160 qpd->bufsize = count * 128;
@@ -137,7 +165,7 @@ static int qp_open(struct inode *inode, struct file *file)
137 } 165 }
138 166
139 spin_lock_irq(&qpd->devp->lock); 167 spin_lock_irq(&qpd->devp->lock);
140 idr_for_each(&qpd->devp->qpidr, dump_qps, qpd); 168 idr_for_each(&qpd->devp->qpidr, dump_qp, qpd);
141 spin_unlock_irq(&qpd->devp->lock); 169 spin_unlock_irq(&qpd->devp->lock);
142 170
143 qpd->buf[qpd->pos++] = 0; 171 qpd->buf[qpd->pos++] = 0;
@@ -149,43 +177,84 @@ out:
149 return ret; 177 return ret;
150} 178}
151 179
152static ssize_t qp_read(struct file *file, char __user *buf, size_t count, 180static const struct file_operations qp_debugfs_fops = {
153 loff_t *ppos) 181 .owner = THIS_MODULE,
182 .open = qp_open,
183 .release = qp_release,
184 .read = debugfs_read,
185};
186
187static int dump_stag(int id, void *p, void *data)
154{ 188{
155 struct debugfs_qp_data *qpd = file->private_data; 189 struct c4iw_debugfs_data *stagd = data;
156 loff_t pos = *ppos; 190 int space;
157 loff_t avail = qpd->pos; 191 int cc;
158 192
159 if (pos < 0) 193 space = stagd->bufsize - stagd->pos - 1;
160 return -EINVAL; 194 if (space == 0)
161 if (pos >= avail) 195 return 1;
196
197 cc = snprintf(stagd->buf + stagd->pos, space, "0x%x\n", id<<8);
198 if (cc < space)
199 stagd->pos += cc;
200 return 0;
201}
202
203static int stag_release(struct inode *inode, struct file *file)
204{
205 struct c4iw_debugfs_data *stagd = file->private_data;
206 if (!stagd) {
207 printk(KERN_INFO "%s null stagd?\n", __func__);
162 return 0; 208 return 0;
163 if (count > avail - pos) 209 }
164 count = avail - pos; 210 kfree(stagd->buf);
211 kfree(stagd);
212 return 0;
213}
165 214
166 while (count) { 215static int stag_open(struct inode *inode, struct file *file)
167 size_t len = 0; 216{
217 struct c4iw_debugfs_data *stagd;
218 int ret = 0;
219 int count = 1;
168 220
169 len = min((int)count, (int)qpd->pos - (int)pos); 221 stagd = kmalloc(sizeof *stagd, GFP_KERNEL);
170 if (copy_to_user(buf, qpd->buf + pos, len)) 222 if (!stagd) {
171 return -EFAULT; 223 ret = -ENOMEM;
172 if (len == 0) 224 goto out;
173 return -EINVAL; 225 }
226 stagd->devp = inode->i_private;
227 stagd->pos = 0;
174 228
175 buf += len; 229 spin_lock_irq(&stagd->devp->lock);
176 pos += len; 230 idr_for_each(&stagd->devp->mmidr, count_idrs, &count);
177 count -= len; 231 spin_unlock_irq(&stagd->devp->lock);
232
233 stagd->bufsize = count * sizeof("0x12345678\n");
234 stagd->buf = kmalloc(stagd->bufsize, GFP_KERNEL);
235 if (!stagd->buf) {
236 ret = -ENOMEM;
237 goto err1;
178 } 238 }
179 count = pos - *ppos; 239
180 *ppos = pos; 240 spin_lock_irq(&stagd->devp->lock);
181 return count; 241 idr_for_each(&stagd->devp->mmidr, dump_stag, stagd);
242 spin_unlock_irq(&stagd->devp->lock);
243
244 stagd->buf[stagd->pos++] = 0;
245 file->private_data = stagd;
246 goto out;
247err1:
248 kfree(stagd);
249out:
250 return ret;
182} 251}
183 252
184static const struct file_operations qp_debugfs_fops = { 253static const struct file_operations stag_debugfs_fops = {
185 .owner = THIS_MODULE, 254 .owner = THIS_MODULE,
186 .open = qp_open, 255 .open = stag_open,
187 .release = qp_release, 256 .release = stag_release,
188 .read = qp_read, 257 .read = debugfs_read,
189}; 258};
190 259
191static int setup_debugfs(struct c4iw_dev *devp) 260static int setup_debugfs(struct c4iw_dev *devp)
@@ -199,6 +268,11 @@ static int setup_debugfs(struct c4iw_dev *devp)
199 (void *)devp, &qp_debugfs_fops); 268 (void *)devp, &qp_debugfs_fops);
200 if (de && de->d_inode) 269 if (de && de->d_inode)
201 de->d_inode->i_size = 4096; 270 de->d_inode->i_size = 4096;
271
272 de = debugfs_create_file("stags", S_IWUSR, devp->debugfs_root,
273 (void *)devp, &stag_debugfs_fops);
274 if (de && de->d_inode)
275 de->d_inode->i_size = 4096;
202 return 0; 276 return 0;
203} 277}
204 278