Skip to content

Commit 2071a3e

Browse files
Federico Vagagregkh
authored andcommitted
drivers/fmc: The only way to dump the SDB is from debugfs
Driver should not call fmc_sdb_dump() anymore. (actually they can but the operation is not supported, so it will print an error message) Signed-off-by: Federico Vaga <[email protected]> Tested-by: Pat Riehecky <[email protected]> Acked-by: Alessandro Rubini <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 9f757f4 commit 2071a3e

File tree

7 files changed

+195
-139
lines changed

7 files changed

+195
-139
lines changed

drivers/fmc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ fmc-y += fmc-match.o
66
fmc-y += fmc-sdb.o
77
fmc-y += fru-parse.o
88
fmc-y += fmc-dump.o
9+
fmc-y += fmc-debug.o
910

1011
obj-$(CONFIG_FMC_FAKEDEV) += fmc-fakedev.o
1112
obj-$(CONFIG_FMC_TRIVIAL) += fmc-trivial.o

drivers/fmc/fmc-core.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#include <linux/init.h>
1414
#include <linux/device.h>
1515
#include <linux/fmc.h>
16+
#include <linux/fmc-sdb.h>
17+
18+
#include "fmc-private.h"
1619

1720
static int fmc_check_version(unsigned long version, const char *name)
1821
{
@@ -289,7 +292,7 @@ int fmc_device_register_n(struct fmc_device **devs, int n)
289292
}
290293
/* This device went well, give information to the user */
291294
fmc_dump_eeprom(fmc);
292-
fmc_dump_sdb(fmc);
295+
fmc_debug_init(fmc);
293296
}
294297
return 0;
295298

@@ -301,6 +304,7 @@ int fmc_device_register_n(struct fmc_device **devs, int n)
301304

302305
kfree(devarray);
303306
for (i--; i >= 0; i--) {
307+
fmc_debug_exit(devs[i]);
304308
sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
305309
device_del(&devs[i]->dev);
306310
fmc_free_id_info(devs[i]);
@@ -328,6 +332,7 @@ void fmc_device_unregister_n(struct fmc_device **devs, int n)
328332
kfree(devs[0]->devarray);
329333

330334
for (i = 0; i < n; i++) {
335+
fmc_debug_exit(devs[i]);
331336
sysfs_remove_bin_file(&devs[i]->dev.kobj, &fmc_eeprom_attr);
332337
device_del(&devs[i]->dev);
333338
fmc_free_id_info(devs[i]);

drivers/fmc/fmc-debug.c

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/*
2+
* Copyright (C) 2015 CERN (www.cern.ch)
3+
* Author: Federico Vaga <[email protected]>
4+
*
5+
* Released according to the GNU GPL, version 2 or any later version.
6+
*/
7+
8+
#include <linux/module.h>
9+
#include <linux/device.h>
10+
#include <linux/init.h>
11+
#include <linux/fs.h>
12+
#include <linux/debugfs.h>
13+
#include <linux/seq_file.h>
14+
#include <asm/byteorder.h>
15+
16+
#include <linux/fmc.h>
17+
#include <linux/sdb.h>
18+
#include <linux/fmc-sdb.h>
19+
20+
#define FMC_DBG_SDB_DUMP "dump_sdb"
21+
22+
static char *__strip_trailing_space(char *buf, char *str, int len)
23+
{
24+
int i = len - 1;
25+
26+
memcpy(buf, str, len);
27+
buf[len] = '\0';
28+
while (i >= 0 && buf[i] == ' ')
29+
buf[i--] = '\0';
30+
return buf;
31+
}
32+
33+
#define __sdb_string(buf, field) ({ \
34+
BUILD_BUG_ON(sizeof(buf) < sizeof(field)); \
35+
__strip_trailing_space(buf, (void *)(field), sizeof(field)); \
36+
})
37+
38+
/**
39+
* We do not check seq_printf() errors because we want to see things in any case
40+
*/
41+
static void fmc_sdb_dump_recursive(struct fmc_device *fmc, struct seq_file *s,
42+
const struct sdb_array *arr)
43+
{
44+
unsigned long base = arr->baseaddr;
45+
int i, j, n = arr->len, level = arr->level;
46+
char tmp[64];
47+
48+
for (i = 0; i < n; i++) {
49+
union sdb_record *r;
50+
struct sdb_product *p;
51+
struct sdb_component *c;
52+
53+
r = &arr->record[i];
54+
c = &r->dev.sdb_component;
55+
p = &c->product;
56+
57+
for (j = 0; j < level; j++)
58+
seq_printf(s, " ");
59+
switch (r->empty.record_type) {
60+
case sdb_type_interconnect:
61+
seq_printf(s, "%08llx:%08x %.19s\n",
62+
__be64_to_cpu(p->vendor_id),
63+
__be32_to_cpu(p->device_id),
64+
p->name);
65+
break;
66+
case sdb_type_device:
67+
seq_printf(s, "%08llx:%08x %.19s (%08llx-%08llx)\n",
68+
__be64_to_cpu(p->vendor_id),
69+
__be32_to_cpu(p->device_id),
70+
p->name,
71+
__be64_to_cpu(c->addr_first) + base,
72+
__be64_to_cpu(c->addr_last) + base);
73+
break;
74+
case sdb_type_bridge:
75+
seq_printf(s, "%08llx:%08x %.19s (bridge: %08llx)\n",
76+
__be64_to_cpu(p->vendor_id),
77+
__be32_to_cpu(p->device_id),
78+
p->name,
79+
__be64_to_cpu(c->addr_first) + base);
80+
if (IS_ERR(arr->subtree[i])) {
81+
seq_printf(s, "SDB: (bridge error %li)\n",
82+
PTR_ERR(arr->subtree[i]));
83+
break;
84+
}
85+
fmc_sdb_dump_recursive(fmc, s, arr->subtree[i]);
86+
break;
87+
case sdb_type_integration:
88+
seq_printf(s, "integration\n");
89+
break;
90+
case sdb_type_repo_url:
91+
seq_printf(s, "Synthesis repository: %s\n",
92+
__sdb_string(tmp, r->repo_url.repo_url));
93+
break;
94+
case sdb_type_synthesis:
95+
seq_printf(s, "Bitstream '%s' ",
96+
__sdb_string(tmp, r->synthesis.syn_name));
97+
seq_printf(s, "synthesized %08x by %s ",
98+
__be32_to_cpu(r->synthesis.date),
99+
__sdb_string(tmp, r->synthesis.user_name));
100+
seq_printf(s, "(%s version %x), ",
101+
__sdb_string(tmp, r->synthesis.tool_name),
102+
__be32_to_cpu(r->synthesis.tool_version));
103+
seq_printf(s, "commit %pm\n",
104+
r->synthesis.commit_id);
105+
break;
106+
case sdb_type_empty:
107+
seq_printf(s, "empty\n");
108+
break;
109+
default:
110+
seq_printf(s, "UNKNOWN TYPE 0x%02x\n",
111+
r->empty.record_type);
112+
break;
113+
}
114+
}
115+
}
116+
117+
static int fmc_sdb_dump(struct seq_file *s, void *offset)
118+
{
119+
struct fmc_device *fmc = s->private;
120+
121+
if (!fmc->sdb) {
122+
seq_printf(s, "no SDB information\n");
123+
return 0;
124+
}
125+
126+
seq_printf(s, "FMC: %s (%s), slot %i, device %s\n", dev_name(fmc->hwdev),
127+
fmc->carrier_name, fmc->slot_id, dev_name(&fmc->dev));
128+
/* Dump SDB information */
129+
fmc_sdb_dump_recursive(fmc, s, fmc->sdb);
130+
131+
return 0;
132+
}
133+
134+
135+
static int fmc_sdb_dump_open(struct inode *inode, struct file *file)
136+
{
137+
struct fmc_device *fmc = inode->i_private;
138+
139+
return single_open(file, fmc_sdb_dump, fmc);
140+
}
141+
142+
143+
const struct file_operations fmc_dbgfs_sdb_dump = {
144+
.owner = THIS_MODULE,
145+
.open = fmc_sdb_dump_open,
146+
.read = seq_read,
147+
.llseek = seq_lseek,
148+
.release = single_release,
149+
};
150+
151+
int fmc_debug_init(struct fmc_device *fmc)
152+
{
153+
fmc->dbg_dir = debugfs_create_dir(dev_name(&fmc->dev), NULL);
154+
if (IS_ERR_OR_NULL(fmc->dbg_dir)) {
155+
pr_err("FMC: Cannot create debugfs\n");
156+
return PTR_ERR(fmc->dbg_dir);
157+
}
158+
159+
fmc->dbg_sdb_dump = debugfs_create_file(FMC_DBG_SDB_DUMP, 0444,
160+
fmc->dbg_dir, fmc,
161+
&fmc_dbgfs_sdb_dump);
162+
if (IS_ERR_OR_NULL(fmc->dbg_sdb_dump))
163+
pr_err("FMC: Cannot create debugfs file %s\n",
164+
FMC_DBG_SDB_DUMP);
165+
166+
return 0;
167+
}
168+
169+
void fmc_debug_exit(struct fmc_device *fmc)
170+
{
171+
if (fmc->dbg_dir)
172+
debugfs_remove_recursive(fmc->dbg_dir);
173+
}

drivers/fmc/fmc-dump.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
static int fmc_must_dump_eeprom;
1717
module_param_named(dump_eeprom, fmc_must_dump_eeprom, int, 0644);
18-
static int fmc_must_dump_sdb;
19-
module_param_named(dump_sdb, fmc_must_dump_sdb, int, 0644);
2018

2119
#define LINELEN 16
2220

@@ -59,42 +57,3 @@ void fmc_dump_eeprom(const struct fmc_device *fmc)
5957
for (i = 0; i < fmc->eeprom_len; i += LINELEN, line += LINELEN)
6058
prev = dump_line(i, line, prev);
6159
}
62-
63-
void fmc_dump_sdb(const struct fmc_device *fmc)
64-
{
65-
const uint8_t *line, *prev;
66-
int i, len;
67-
68-
if (!fmc->sdb)
69-
return;
70-
if (!fmc_must_dump_sdb)
71-
return;
72-
73-
/* If the argument is not-zero, do simple dump (== show) */
74-
if (fmc_must_dump_sdb > 0)
75-
fmc_show_sdb_tree(fmc);
76-
77-
if (fmc_must_dump_sdb == 1)
78-
return;
79-
80-
/* If bigger than 1, dump it seriously, to help debugging */
81-
82-
/*
83-
* Here we should really use libsdbfs (which is designed to
84-
* work in kernel space as well) , but it doesn't support
85-
* directories yet, and it requires better intergration (it
86-
* should be used instead of fmc-specific code).
87-
*
88-
* So, lazily, just dump the top-level array
89-
*/
90-
pr_info("FMC: %s (%s), slot %i, device %s\n", dev_name(fmc->hwdev),
91-
fmc->carrier_name, fmc->slot_id, dev_name(&fmc->dev));
92-
pr_info("FMC: poor dump of sdb first level:\n");
93-
94-
len = fmc->sdb->len * sizeof(union sdb_record);
95-
line = (void *)fmc->sdb->record;
96-
prev = NULL;
97-
for (i = 0; i < len; i += LINELEN, line += LINELEN)
98-
prev = dump_line(i, line, prev);
99-
return;
100-
}

drivers/fmc/fmc-private.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (C) 2015 CERN (www.cern.ch)
3+
* Author: Federico Vaga <[email protected]>
4+
*
5+
* Released according to the GNU GPL, version 2 or any later version.
6+
*/
7+
8+
extern int fmc_debug_init(struct fmc_device *fmc);
9+
extern void fmc_debug_exit(struct fmc_device *fmc);

drivers/fmc/fmc-sdb.c

Lines changed: 3 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -145,108 +145,15 @@ int fmc_reprogram(struct fmc_device *fmc, struct fmc_driver *d, char *gw,
145145
sdb_entry);
146146
return -ENODEV;
147147
}
148-
fmc_dump_sdb(fmc);
148+
149149
return 0;
150150
}
151151
EXPORT_SYMBOL(fmc_reprogram);
152152

153-
static char *__strip_trailing_space(char *buf, char *str, int len)
154-
{
155-
int i = len - 1;
156-
157-
memcpy(buf, str, len);
158-
while(i >= 0 && buf[i] == ' ')
159-
buf[i--] = '\0';
160-
return buf;
161-
}
162-
163-
#define __sdb_string(buf, field) ({ \
164-
BUILD_BUG_ON(sizeof(buf) < sizeof(field)); \
165-
__strip_trailing_space(buf, (void *)(field), sizeof(field)); \
166-
})
167-
168-
static void __fmc_show_sdb_tree(const struct fmc_device *fmc,
169-
const struct sdb_array *arr)
170-
{
171-
unsigned long base = arr->baseaddr;
172-
int i, j, n = arr->len, level = arr->level;
173-
char buf[64];
174-
175-
for (i = 0; i < n; i++) {
176-
union sdb_record *r;
177-
struct sdb_product *p;
178-
struct sdb_component *c;
179-
r = &arr->record[i];
180-
c = &r->dev.sdb_component;
181-
p = &c->product;
182-
183-
dev_info(&fmc->dev, "SDB: ");
184-
185-
for (j = 0; j < level; j++)
186-
printk(KERN_CONT " ");
187-
switch (r->empty.record_type) {
188-
case sdb_type_interconnect:
189-
printk(KERN_CONT "%08llx:%08x %.19s\n",
190-
__be64_to_cpu(p->vendor_id),
191-
__be32_to_cpu(p->device_id),
192-
p->name);
193-
break;
194-
case sdb_type_device:
195-
printk(KERN_CONT "%08llx:%08x %.19s (%08llx-%08llx)\n",
196-
__be64_to_cpu(p->vendor_id),
197-
__be32_to_cpu(p->device_id),
198-
p->name,
199-
__be64_to_cpu(c->addr_first) + base,
200-
__be64_to_cpu(c->addr_last) + base);
201-
break;
202-
case sdb_type_bridge:
203-
printk(KERN_CONT "%08llx:%08x %.19s (bridge: %08llx)\n",
204-
__be64_to_cpu(p->vendor_id),
205-
__be32_to_cpu(p->device_id),
206-
p->name,
207-
__be64_to_cpu(c->addr_first) + base);
208-
if (IS_ERR(arr->subtree[i])) {
209-
dev_info(&fmc->dev, "SDB: (bridge error %li)\n",
210-
PTR_ERR(arr->subtree[i]));
211-
break;
212-
}
213-
__fmc_show_sdb_tree(fmc, arr->subtree[i]);
214-
break;
215-
case sdb_type_integration:
216-
printk(KERN_CONT "integration\n");
217-
break;
218-
case sdb_type_repo_url:
219-
printk(KERN_CONT "Synthesis repository: %s\n",
220-
__sdb_string(buf, r->repo_url.repo_url));
221-
break;
222-
case sdb_type_synthesis:
223-
printk(KERN_CONT "Bitstream '%s' ",
224-
__sdb_string(buf, r->synthesis.syn_name));
225-
printk(KERN_CONT "synthesized %08x by %s ",
226-
__be32_to_cpu(r->synthesis.date),
227-
__sdb_string(buf, r->synthesis.user_name));
228-
printk(KERN_CONT "(%s version %x), ",
229-
__sdb_string(buf, r->synthesis.tool_name),
230-
__be32_to_cpu(r->synthesis.tool_version));
231-
printk(KERN_CONT "commit %pm\n",
232-
r->synthesis.commit_id);
233-
break;
234-
case sdb_type_empty:
235-
printk(KERN_CONT "empty\n");
236-
break;
237-
default:
238-
printk(KERN_CONT "UNKNOWN TYPE 0x%02x\n",
239-
r->empty.record_type);
240-
break;
241-
}
242-
}
243-
}
244-
245153
void fmc_show_sdb_tree(const struct fmc_device *fmc)
246154
{
247-
if (!fmc->sdb)
248-
return;
249-
__fmc_show_sdb_tree(fmc, fmc->sdb);
155+
pr_err("%s: not supported anymore, use debugfs to dump SDB\n",
156+
__func__);
250157
}
251158
EXPORT_SYMBOL(fmc_show_sdb_tree);
252159

0 commit comments

Comments
 (0)