AFHBA404
AFHBA404 connects ACQ2106 to PCI-Express
afs_procfs.c
Go to the documentation of this file.
1 /* ------------------------------------------------------------------------- */
2 /* acq400_drv.c D-TACQ ACQ400 FMC DRIVER
3  * afs_procfs.c
4  *
5  * Created on: 22 Jan 2015
6  * Author: pgm
7  */
8 
9 /* ------------------------------------------------------------------------- */
10 /* Copyright (C) 2015 Peter Milne, D-TACQ Solutions Ltd *
11  * <peter dot milne at D hyphen TACQ dot com> *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of Version 2 of the GNU General Public License *
15  * as published by the Free Software Foundation; *
16  * *
17  * This program is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  * You should have received a copy of the GNU General Public License *
23  * along with this program; if not, write to the Free Software *
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25 /* ------------------------------------------------------------------------- */
26 
27 #include <linux/seq_file.h>
28 #include <linux/proc_fs.h>
29 
30 #include "acq-fiber-hba.h"
31 #include "afhba_stream_drv.h"
32 
33 extern int nbuffers;
34 extern struct list_head afhba_devices;
35 
36 struct proc_dir_entry *afs_proc_root;
37 
38 static void *hb_seq_start(struct seq_file *sfile, loff_t *pos)
39 /* *pos == iblock. returns next TBLOCK* */
40 {
41  if (*pos >= nbuffers){
42  return NULL;
43  }else{
44  return pos;
45  }
46 }
47 
48 static void *hb_seq_next(struct seq_file *s, void *v, loff_t *pos)
49 {
50  (*pos)++;
51  if (*pos >= nbuffers){
52  return NULL;
53  }else{
54  return pos;
55  }
56 }
57 
58 
59 
60 static void hb_seq_stop(struct seq_file *s, void *v) {}
61 
62 
63 static inline const char *BSTATE2S(enum BSTATE bstate)
64 {
65  switch(bstate){
66  case BS_EMPTY: return "BS_EMPTY";
67  case BS_FILLING: return "BS_FILLING";
68  case BS_FULL: return "BS_FULL";
69  case BS_FULL_APP: return "BS_FULL_APP";
70  default: return "BS_ERROR";
71  }
72 }
73 
74 
75 static int hb_seq_show(struct seq_file *sfile, void *v)
76 {
77  struct file *file = (struct file *)sfile->private;
78  struct AFHBA_DEV *adev = PDE_DATA(file_inode(file));
79  struct AFHBA_STREAM_DEV *sdev = adev->stream_dev;
80  int ib = *(int*)v;
81  struct HostBuffer *hb = sdev->hbx+ib;
82 
83  if (ib == 0){
84  seq_printf(sfile, "ix va pa len req_len descr state\n");
85  }
86  seq_printf(sfile,
87  "[%02d] %p %08x %06x %06x %08x %s\n",
88  ib, hb->va, hb->pa, hb->len, hb->req_len,
89  hb->descr, BSTATE2S(hb->bstate));
90  return 0;
91 }
92 
93 static int hbd_seq_show(struct seq_file *sfile, void *v)
94 {
95  struct file *file = (struct file *)sfile->private;
96  struct AFHBA_DEV *adev = PDE_DATA(file_inode(file));
97  struct AFHBA_STREAM_DEV *sdev = adev->stream_dev;
98  int ib = *(int*)v;
99  struct HostBuffer *hb = sdev->hbx+ib;
100 
101  seq_printf(sfile, "%08x\n", hb->descr);
102  return 0;
103 }
104 
105 
106 
107 
108 static int ab_seq_show(struct seq_file *sfile, void *v)
109 /* shows buffers that are FULL but NOT in FULL LIST */
110 {
111  struct file *file = (struct file *)sfile->private;
112  struct AFHBA_DEV *adev = PDE_DATA(file_inode(file));
113  struct AFHBA_STREAM_DEV *sdev = adev->stream_dev;
114  int ib = *(int*)v;
115  struct HostBuffer *hb = sdev->hbx+ib;
116 
117  if (ib == 0){
118  seq_printf(sfile, "ix va pa len req_len descr state\n");
119  }
120  if (hb->bstate == BS_FULL_APP){
121  seq_printf(sfile,
122  "[%02d] %p %08x %06x %06x %08x %s\n",
123  ib, hb->va, hb->pa, hb->len, hb->req_len,
124  hb->descr, BSTATE2S(hb->bstate));
125  }
126  return 0;
127 }
128 
129 
130 static int __proc_open(
131  struct inode *inode, struct file *file,
132  struct seq_operations *_seq_ops)
133 {
134  int rc = seq_open(file, _seq_ops);
135 
136  if (rc == 0){
137  struct seq_file* seq_file =
138  (struct seq_file*)file->private_data;
139  seq_file->private = file;
140  }
141 
142  return rc;
143 }
144 
145 static int hb_proc_open(struct inode *inode, struct file *file)
146 {
147  static struct seq_operations _seq_ops = {
148  .start = hb_seq_start,
149  .next = hb_seq_next,
150  .stop = hb_seq_stop,
151  .show = hb_seq_show
152  };
153  return __proc_open(inode, file, &_seq_ops);
154 }
155 static int hbd_proc_open(struct inode *inode, struct file *file)
156 {
157  static struct seq_operations _seq_ops = {
158  .start = hb_seq_start,
159  .next = hb_seq_next,
160  .stop = hb_seq_stop,
161  .show = hbd_seq_show
162  };
163  return __proc_open(inode, file, &_seq_ops);
164 }
165 
166 static int addHostBufferProcFiles(struct AFHBA_DEV *adev)
167 {
168  static struct file_operations hb_proc_fops = {
169  .owner = THIS_MODULE,
170  .open = hb_proc_open,
171  .read = seq_read,
172  .llseek = seq_lseek,
173  .release = seq_release
174  };
175  static struct file_operations hbd_proc_fops = {
176  .owner = THIS_MODULE,
177  .open = hbd_proc_open,
178  .read = seq_read,
179  .llseek = seq_lseek,
180  .release = seq_release
181  };
182  struct AFHBA_STREAM_DEV *sdev = adev->stream_dev;
183  struct proc_dir_entry *hb_entry =
184  proc_create_data("HostBuffers", S_IRUGO,
185  sdev->proc_dir_root, &hb_proc_fops, adev);
186 
187  if (hb_entry){
188  hb_entry = proc_create_data("HostDescriptors", S_IRUGO,
189  sdev->proc_dir_root, &hbd_proc_fops, adev);
190  if (hb_entry){
191  return 0;
192  }
193  }
194 
195  dev_err(pdev(adev), "Failed to create entry");
196  return -1;
197 }
198 
199 static int ab_proc_open(struct inode *inode, struct file *file)
200 {
201  static struct seq_operations _seq_ops = {
202  .start = hb_seq_start,
203  .next = hb_seq_next,
204  .stop = hb_seq_stop,
205  .show = ab_seq_show
206  };
207  return __proc_open(inode, file, &_seq_ops);
208 }
209 
210 static int addAppBufferProcFiles(struct AFHBA_DEV *adev)
211 {
212  static struct file_operations ab_proc_fops = {
213  .owner = THIS_MODULE,
214  .open = ab_proc_open,
215  .read = seq_read,
216  .llseek = seq_lseek,
217  .release = seq_release
218  };
219  struct AFHBA_STREAM_DEV *sdev = adev->stream_dev;
220  struct proc_dir_entry *ab_entry =
221  proc_create_data("AppBuffers", S_IRUGO,
222  sdev->proc_dir_root, &ab_proc_fops, adev);
223  if (ab_entry){
224  return 0;
225  }
226 
227  dev_err(pdev(adev), "Failed to create entry");
228  return -1;
229 }
230 
231 static int job_proc_show(struct seq_file *m, void *v)
232  {
233  struct file *file = (struct file *)m->private;
234  struct AFHBA_DEV *adev = PDE_DATA(file_inode(file));
235  struct AFHBA_STREAM_DEV *sdev = adev->stream_dev;
236  struct JOB *job = &sdev->job;
237  int bstates[NSTATES] = { 0, };
238  int ii;
239  int data_rate = job->rx_rate*sdev->req_len;
240 
241  if (data_rate > 0x100000){
242  data_rate /= 0x100000;
243  }
244 
245  for (ii = 0; ii != nbuffers; ++ii){
246  int bs = sdev->hbx[ii].bstate;
247  if (bs < 0 || bs > NSTATES-1){
248  dev_warn(pdev(adev), "bstate[%d] %d out of range", ii, bs);
249  }else{
250  bstates[bs]++;
251  }
252  }
253 
254  seq_printf(m,
255  "dev=%s idx=%d demand=%d queued=%d "
256  "rx=%d rx_rate=%d int_rate=%d "
257  "MBPS=%d "
258  "BS_EMPTY=%-2d BS_FILLING=%-2d BS_FULL=%-2d BS_FULL_APP=%-2d "
259  "STATUS=%s ERRORS=%d\n",
260  adev->name, adev->idx,
261  job->buffers_demand,
262  job->buffers_queued,
263  job->buffers_received,
264  job->rx_rate, job->int_rate,
265  data_rate,
266  bstates[0], bstates[1], bstates[2], bstates[3],
267  job->please_stop==PS_PLEASE_STOP? "PLEASE_STOP":
268  job->please_stop==PS_STOP_DONE? "STOP_DONE": "",
269  job->errors
270  );
271  return 0;
272  }
273 
274 static int job_proc_open(struct inode *inode, struct file *file)
275 {
276  return single_open(file, job_proc_show, file);
277 }
278 static int addJobProcFile(struct AFHBA_DEV *adev)
279 {
280  struct AFHBA_STREAM_DEV *sdev = adev->stream_dev;
281  static struct file_operations job_proc_fops = {
282  .owner = THIS_MODULE,
283  .open = job_proc_open,
284  .read = seq_read,
285  .llseek = seq_lseek,
286  .release = single_release
287  };
288  if (proc_create_data("Job", S_IRUGO,
289  sdev->proc_dir_root, &job_proc_fops, adev) != 0){
290  return 0;
291  }else{
292  dev_err(pdev(adev), "Failed to create entry");
293  return -1;
294  }
295 }
296 int afs_init_procfs(struct AFHBA_DEV *adev)
297 {
298  struct AFHBA_STREAM_DEV *sdev = adev->stream_dev;
299  int rc;
300 
301  if (!afs_proc_root){
302  afs_proc_root = proc_mkdir("driver/afhba", NULL);
304  }
305 
306  sdev->proc_dir_root = proc_mkdir(adev->name, afs_proc_root);
307 
308  if ((rc = addHostBufferProcFiles(adev)) == 0 &&
309  (rc = addAppBufferProcFiles(adev)) == 0 &&
310  (rc = addJobProcFile(adev) == 0) == 0){
311  return 0;
312  }
313 
314  return rc;
315 }
HostBuffer::pa
u32 pa
Definition: acq-fiber-hba.h:97
AFHBA_STREAM_DEV::hbx
struct HostBuffer * hbx
Definition: afhba_stream_drv.h:84
pdev
#define pdev(adev)
Definition: acq-fiber-hba.h:176
afs_proc_root
struct proc_dir_entry * afs_proc_root
Definition: afs_procfs.c:36
NSTATES
#define NSTATES
Definition: afhba_stream_drv.h:23
afs_init_procfs
int afs_init_procfs(struct AFHBA_DEV *adev)
Definition: afs_procfs.c:296
AFHBA_STREAM_DEV::req_len
int req_len
Definition: afhba_stream_drv.h:133
HostBuffer::bstate
enum HostBuffer::BSTATE bstate
AFHBA_STREAM_DEV::proc_dir_root
struct proc_dir_entry * proc_dir_root
Definition: afhba_stream_drv.h:87
AFHBA_DEV::stream_dev
struct AFHBA_STREAM_DEV * stream_dev
Definition: acq-fiber-hba.h:143
HostBuffer::BS_FULL_APP
@ BS_FULL_APP
Definition: acq-fiber-hba.h:103
ib
int ib
Definition: InlineDataHandlerMuxAO_LLC.cpp:57
afhba_stream_drv.h
AFHBA_DEV::idx
int idx
Definition: acq-fiber-hba.h:117
afhba_devices
struct list_head afhba_devices
HostBuffer::descr
u32 descr
Definition: acq-fiber-hba.h:100
AFHBA_STREAM_DEV::JOB::rx_rate
unsigned rx_rate
Definition: afhba_stream_drv.h:97
AFHBA_DEV
Definition: acq-fiber-hba.h:111
AFHBA_STREAM_DEV::job
struct AFHBA_STREAM_DEV::JOB job
HostBuffer::va
void * va
Definition: acq-fiber-hba.h:96
PS_PLEASE_STOP
@ PS_PLEASE_STOP
Definition: afhba_stream_drv.h:53
AFHBA_DEV::name
char name[16]
Definition: acq-fiber-hba.h:112
AFHBA_STREAM_DEV
Definition: afhba_stream_drv.h:66
assert
#define assert(p)
Definition: acq-fiber-hba.h:55
HostBuffer::len
int len
Definition: acq-fiber-hba.h:98
PS_STOP_DONE
@ PS_STOP_DONE
Definition: afhba_stream_drv.h:53
HostBuffer
Definition: acq-fiber-hba.h:94
nbuffers
int nbuffers
Definition: afhba_stream_drv.c:73
acq-fiber-hba.h
HostBuffer::req_len
int req_len
Definition: acq-fiber-hba.h:99