diff options
-rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 152 |
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 | ||
50 | static struct dentry *c4iw_debugfs_root; | 50 | static struct dentry *c4iw_debugfs_root; |
51 | 51 | ||
52 | struct debugfs_qp_data { | 52 | struct 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 | ||
59 | static int count_qps(int id, void *p, void *data) | 59 | static 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 | ||
71 | static int dump_qps(int id, void *p, void *data) | 67 | static 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 | |||
99 | static 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 | ||
102 | static int qp_release(struct inode *inode, struct file *file) | 130 | static 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 | ||
114 | static int qp_open(struct inode *inode, struct file *file) | 142 | static 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 | ||
152 | static ssize_t qp_read(struct file *file, char __user *buf, size_t count, | 180 | static 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 | |||
187 | static 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 | |||
203 | static 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) { | 215 | static 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; | ||
247 | err1: | ||
248 | kfree(stagd); | ||
249 | out: | ||
250 | return ret; | ||
182 | } | 251 | } |
183 | 252 | ||
184 | static const struct file_operations qp_debugfs_fops = { | 253 | static 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 | ||
191 | static int setup_debugfs(struct c4iw_dev *devp) | 260 | static 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 | ||