Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Software for White Rabbit PTP Core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
32
Issues
32
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Software for White Rabbit PTP Core
Commits
9db373ba
Commit
9db373ba
authored
Nov 18, 2014
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sdb-for-all'
parents
32dd97e9
42e0449f
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
366 additions
and
225 deletions
+366
-225
Kconfig
Kconfig
+3
-2
dev.mk
dev/dev.mk
+1
-1
devicelist.c
dev/devicelist.c
+90
-0
sdb-eeprom.c
dev/sdb-eeprom.c
+99
-14
sdb.c
dev/sdb.c
+0
-161
access.c
sdb-lib/access.c
+4
-2
glue.c
sdb-lib/glue.c
+136
-32
libsdbfs-kernel.h
sdb-lib/libsdbfs-kernel.h
+14
-3
libsdbfs.h
sdb-lib/libsdbfs.h
+19
-10
No files found.
Kconfig
View file @
9db373ba
...
...
@@ -204,10 +204,11 @@ config UART_SW
and diagnostics run on the hardware UART if available.
config SDB_EEPROM
de
pends on DEVELOPER && W1
de
fault y
boolean "Use SDB to manage EEPROM (instead of legacy code)"
help
New experimental code to unify W1 and EEPROM storage
Use SDB to manage eeproms, both W1 and I2C. If not, legacy code
will be selected.
config LEGACY_EEPROM
boolean
...
...
dev/dev.mk
View file @
9db373ba
...
...
@@ -6,7 +6,7 @@ obj-$(CONFIG_WR_NODE) += \
dev/pps_gen.o \
dev/syscon.o \
dev/sfp.o \
dev/
sdb
.o \
dev/
devicelist
.o \
dev/rxts_calibrator.o
obj-$(CONFIG_WR_SWITCH) += dev/timer-wrs.o dev/ad9516.o
...
...
dev/devicelist.c
0 → 100644
View file @
9db373ba
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2014 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <wrc.h>
#define SDBFS_BIG_ENDIAN
#include <libsdbfs.h>
/* The following pointers are exported */
unsigned
char
*
BASE_MINIC
;
unsigned
char
*
BASE_EP
;
unsigned
char
*
BASE_SOFTPLL
;
unsigned
char
*
BASE_PPS_GEN
;
unsigned
char
*
BASE_SYSCON
;
unsigned
char
*
BASE_UART
;
unsigned
char
*
BASE_ONEWIRE
;
unsigned
char
*
BASE_ETHERBONE_CFG
;
/* The sdb filesystem itself */
static
struct
sdbfs
wrc_fpga_sdb
=
{
.
name
=
"fpga-area"
,
.
blocksize
=
1
,
/* Not currently used */
.
entrypoint
=
SDB_ADDRESS
,
.
data
=
0
,
.
flags
=
SDBFS_F_ZEROBASED
,
};
/* called by outside, at boot time */
void
sdb_print_devices
(
void
)
{
struct
sdb_device
*
d
;
int
new
=
1
;
while
(
(
d
=
sdbfs_scan
(
&
wrc_fpga_sdb
,
new
))
!=
NULL
)
{
/*
* "%.19s" is not working for XINT printf, and zeroing
* d->sdb_component.product.record_type won't work, as
* the device is read straight from fpga ROM registers
*/
const
int
namesize
=
sizeof
(
d
->
sdb_component
.
product
.
name
);
char
name
[
namesize
+
1
];
memcpy
(
name
,
d
->
sdb_component
.
product
.
name
,
sizeof
(
name
));
name
[
namesize
]
=
'\0'
;
pp_printf
(
"dev 0x%08lx @ %06lx, %s
\n
"
,
(
long
)(
d
->
sdb_component
.
product
.
device_id
),
wrc_fpga_sdb
.
f_offset
,
name
);
new
=
0
;
}
}
/* To save a little size, we enumerate our vendors */
#define VID_CERN 0x0000ce42LL
#define VID_GSI 0x00000651LL
struct
wrc_device
{
unsigned
char
**
base
;
uint64_t
vid
;
uint32_t
did
;
};
struct
wrc_device
devs
[]
=
{
{
&
BASE_MINIC
,
VID_CERN
,
0xab28633a
},
{
&
BASE_EP
,
VID_CERN
,
0x650c2d4f
},
{
&
BASE_SOFTPLL
,
VID_CERN
,
0x65158dc0
},
{
&
BASE_PPS_GEN
,
VID_CERN
,
0xde0d8ced
},
{
&
BASE_SYSCON
,
VID_CERN
,
0xff07fc47
},
{
&
BASE_UART
,
VID_CERN
,
0xe2d13d04
},
{
&
BASE_ONEWIRE
,
VID_CERN
,
0x779c5443
},
{
&
BASE_ETHERBONE_CFG
,
VID_GSI
,
0x68202b22
},
};
void
sdb_find_devices
(
void
)
{
struct
wrc_device
*
d
;
static
int
done
;
int
i
;
if
(
!
done
)
{
sdbfs_dev_create
(
&
wrc_fpga_sdb
);
done
++
;
}
for
(
d
=
devs
,
i
=
0
;
i
<
ARRAY_SIZE
(
devs
);
d
++
,
i
++
)
{
*
(
d
->
base
)
=
(
void
*
)
sdbfs_find_id
(
&
wrc_fpga_sdb
,
d
->
vid
,
d
->
did
);
}
}
dev/sdb-eeprom.c
View file @
9db373ba
...
...
@@ -12,8 +12,8 @@
#include <w1.h>
#include <eeprom.h>
//
#include "types.h"
//
#include "i2c.h"
#include "types.h"
#include "i2c.h"
//#include "eeprom.h"
//#include "board.h"
//#include "syscon.h"
...
...
@@ -43,8 +43,72 @@ static int sdb_w1_write(struct sdbfs *fs, int offset, void *buf, int count)
return
w1_write_eeprom_bus
(
fs
->
drvdata
,
offset
,
buf
,
count
);
}
/* The methods for I2C access -- FIXME */
/*
* I2C code.
* The functions in ./eeprom.c (legacy) are replicated here with the sdb
* calling convention. So we miss the low-level and high-level layer splitting
*/
struct
i2c_params
{
int
ifnum
;
int
addr
;
};
static
struct
i2c_params
i2c_params
;
static
int
sdb_i2c_read
(
struct
sdbfs
*
fs
,
int
offset
,
void
*
buf
,
int
count
)
{
int
i
;
struct
i2c_params
*
p
=
fs
->
drvdata
;
unsigned
char
*
cb
=
buf
;
mi2c_start
(
p
->
ifnum
);
if
(
mi2c_put_byte
(
p
->
ifnum
,
p
->
addr
<<
1
)
<
0
)
{
mi2c_stop
(
p
->
ifnum
);
return
-
1
;
}
mi2c_put_byte
(
p
->
ifnum
,
(
offset
>>
8
)
&
0xff
);
mi2c_put_byte
(
p
->
ifnum
,
offset
&
0xff
);
mi2c_repeat_start
(
p
->
ifnum
);
mi2c_put_byte
(
p
->
ifnum
,
(
p
->
addr
<<
1
)
|
1
);
for
(
i
=
0
;
i
<
count
-
1
;
++
i
)
{
mi2c_get_byte
(
p
->
ifnum
,
cb
,
0
);
cb
++
;
}
mi2c_get_byte
(
p
->
ifnum
,
cb
,
1
);
cb
++
;
mi2c_stop
(
p
->
ifnum
);
return
count
;
}
static
int
sdb_i2c_write
(
struct
sdbfs
*
fs
,
int
offset
,
void
*
buf
,
int
count
)
{
int
i
,
busy
;
struct
i2c_params
*
p
=
fs
->
drvdata
;
unsigned
char
*
cb
=
buf
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
mi2c_start
(
p
->
ifnum
);
if
(
mi2c_put_byte
(
p
->
ifnum
,
p
->
addr
<<
1
)
<
0
)
{
mi2c_stop
(
p
->
ifnum
);
return
-
1
;
}
mi2c_put_byte
(
p
->
ifnum
,
(
offset
>>
8
)
&
0xff
);
mi2c_put_byte
(
p
->
ifnum
,
offset
&
0xff
);
mi2c_put_byte
(
p
->
ifnum
,
*
cb
++
);
offset
++
;
mi2c_stop
(
p
->
ifnum
);
do
{
/* wait until the chip becomes ready */
mi2c_start
(
p
->
ifnum
);
busy
=
mi2c_put_byte
(
p
->
ifnum
,
p
->
addr
<<
1
);
mi2c_stop
(
p
->
ifnum
);
}
while
(
busy
);
}
return
count
;
}
/*
* A trivial dumper, just to show what's up in there
...
...
@@ -62,11 +126,13 @@ static void eeprom_sdb_list(struct sdbfs *fs)
new
=
0
;
}
}
/* The sdb filesystem itself */
/* The sdb filesystem itself
, build-time initialized for i2c
*/
static
struct
sdbfs
wrc_sdb
=
{
.
name
=
"
wrpc-storage
"
,
.
name
=
"
eeprom
"
,
.
blocksize
=
1
,
/* Not currently used */
/* .read and .write according to device type */
.
drvdata
=
&
i2c_params
,
.
read
=
sdb_i2c_read
,
.
write
=
sdb_i2c_write
,
};
uint8_t
has_eeprom
=
0
;
/* modified at init time */
...
...
@@ -82,7 +148,7 @@ uint8_t eeprom_present(uint8_t i2cif, uint8_t i2c_addr)
static
unsigned
entry_points
[]
=
{
0
,
64
,
128
,
256
,
512
,
1024
};
int
i
,
ret
;
/* Look for w1 first: if there is no eeprom i
f
fails fast */
/* Look for w1 first: if there is no eeprom i
t
fails fast */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
entry_points
);
i
++
)
{
ret
=
w1_read_eeprom_bus
(
&
wrpc_w1_bus
,
entry_points
[
i
],
(
void
*
)
&
magic
,
sizeof
(
magic
));
...
...
@@ -93,21 +159,40 @@ uint8_t eeprom_present(uint8_t i2cif, uint8_t i2c_addr)
}
if
(
magic
==
SDB_MAGIC
)
{
pp_printf
(
"sdbfs: found at %i in W1
\n
"
,
entry_points
[
i
]);
/* override default i2c settings with w1 ones */
wrc_sdb
.
drvdata
=
&
wrpc_w1_bus
;
wrc_sdb
.
read
=
sdb_w1_read
;
wrc_sdb
.
write
=
sdb_w1_write
;
has_eeprom
=
1
;
eeprom_sdb_list
(
&
wrc_sdb
);
return
0
;
goto
found_exit
;
}
/*
* If w1 failed, look for i2c: start from high offsets by now.
* FIXME: this is a hack, until we have subdirectory support
* If w1 failed, look for i2c: start from low offsets.
*/
for
(
i
=
ARRAY_SIZE
(
entry_points
)
-
i
;
i
>=
0
;
i
--
)
{
/* FIXME: i2c */
if
(
!
mi2c_devprobe
(
i2cif
,
i2c_addr
))
return
0
;
i2c_params
.
ifnum
=
i2cif
;
i2c_params
.
addr
=
i2c_addr
;
/* While looking for the magic number, use sdb-based read function */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
entry_points
);
i
++
)
{
uint32_t
magic
;
sdb_i2c_read
(
&
wrc_sdb
,
entry_points
[
i
],
(
void
*
)
&
magic
,
sizeof
(
magic
));
if
(
magic
==
SDB_MAGIC
)
break
;
}
if
(
i
==
ARRAY_SIZE
(
entry_points
))
{
pp_printf
(
"No SDB filesystem in i2c eeprom
\n
"
);
return
0
;
}
found_exit:
/* found: register the filesystem */
has_eeprom
=
1
;
sdbfs_dev_create
(
&
wrc_sdb
);
eeprom_sdb_list
(
&
wrc_sdb
);
return
0
;
}
...
...
dev/sdb.c
deleted
100644 → 0
View file @
32dd97e9
/*
* This work is part of the White Rabbit project
*
* Copyright (C) 2012 GSI (www.gsi.de)
* Author: Wesley W. Terpstra <w.terpstra@gsi.de>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include <wrc.h>
#include "hw/memlayout.h"
unsigned
char
*
BASE_MINIC
;
unsigned
char
*
BASE_EP
;
unsigned
char
*
BASE_SOFTPLL
;
unsigned
char
*
BASE_PPS_GEN
;
unsigned
char
*
BASE_SYSCON
;
unsigned
char
*
BASE_UART
;
unsigned
char
*
BASE_ONEWIRE
;
unsigned
char
*
BASE_ETHERBONE_CFG
;
#define SDB_INTERCONNET 0x00
#define SDB_DEVICE 0x01
#define SDB_BRIDGE 0x02
#define SDB_EMPTY 0xFF
typedef
struct
pair64
{
uint32_t
high
;
uint32_t
low
;
}
pair64_t
;
struct
sdb_empty
{
int8_t
reserved
[
63
];
uint8_t
record_type
;
};
struct
sdb_product
{
pair64_t
vendor_id
;
uint32_t
device_id
;
uint32_t
version
;
uint32_t
date
;
int8_t
name
[
19
];
uint8_t
record_type
;
};
struct
sdb_component
{
pair64_t
addr_first
;
pair64_t
addr_last
;
struct
sdb_product
product
;
};
struct
sdb_device
{
uint16_t
abi_class
;
uint8_t
abi_ver_major
;
uint8_t
abi_ver_minor
;
uint32_t
bus_specific
;
struct
sdb_component
sdb_component
;
};
struct
sdb_bridge
{
pair64_t
sdb_child
;
struct
sdb_component
sdb_component
;
};
struct
sdb_interconnect
{
uint32_t
sdb_magic
;
uint16_t
sdb_records
;
uint8_t
sdb_version
;
uint8_t
sdb_bus_type
;
struct
sdb_component
sdb_component
;
};
typedef
union
sdb_record
{
struct
sdb_empty
empty
;
struct
sdb_device
device
;
struct
sdb_bridge
bridge
;
struct
sdb_interconnect
interconnect
;
}
sdb_record_t
;
static
unsigned
char
*
find_device_deep
(
unsigned
int
base
,
unsigned
int
sdb
,
unsigned
int
devid
)
{
sdb_record_t
*
record
=
(
sdb_record_t
*
)
sdb
;
int
records
=
record
->
interconnect
.
sdb_records
;
int
i
;
for
(
i
=
0
;
i
<
records
;
++
i
,
++
record
)
{
if
(
record
->
empty
.
record_type
==
SDB_BRIDGE
)
{
unsigned
char
*
out
=
find_device_deep
(
base
+
record
->
bridge
.
sdb_component
.
addr_first
.
low
,
base
+
record
->
bridge
.
sdb_child
.
low
,
devid
);
if
(
out
)
return
out
;
}
if
(
record
->
empty
.
record_type
==
SDB_DEVICE
&&
record
->
device
.
sdb_component
.
product
.
device_id
==
devid
)
{
break
;
}
}
if
(
i
==
records
)
return
0
;
return
(
unsigned
char
*
)(
base
+
record
->
device
.
sdb_component
.
addr_first
.
low
);
}
static
void
print_devices_deep
(
unsigned
int
base
,
unsigned
int
sdb
)
{
sdb_record_t
*
record
=
(
sdb_record_t
*
)
sdb
;
int
records
=
record
->
interconnect
.
sdb_records
;
int
i
;
char
buf
[
20
];
for
(
i
=
0
;
i
<
records
;
++
i
,
++
record
)
{
if
(
record
->
empty
.
record_type
==
SDB_BRIDGE
)
print_devices_deep
(
base
+
record
->
bridge
.
sdb_component
.
addr_first
.
low
,
base
+
record
->
bridge
.
sdb_child
.
low
);
if
(
record
->
empty
.
record_type
!=
SDB_DEVICE
)
continue
;
memcpy
(
buf
,
record
->
device
.
sdb_component
.
product
.
name
,
19
);
buf
[
19
]
=
0
;
mprintf
(
"%8x:%8x 0x%8x %s
\n
"
,
record
->
device
.
sdb_component
.
product
.
vendor_id
.
low
,
record
->
device
.
sdb_component
.
product
.
device_id
,
base
+
record
->
device
.
sdb_component
.
addr_first
.
low
,
buf
);
}
}
static
unsigned
char
*
find_device
(
unsigned
int
devid
)
{
return
find_device_deep
(
0
,
SDB_ADDRESS
,
devid
);
}
void
sdb_print_devices
(
void
)
{
mprintf
(
"SDB memory map:
\n
"
);
print_devices_deep
(
0
,
SDB_ADDRESS
);
mprintf
(
"---
\n
"
);
}
void
sdb_find_devices
(
void
)
{
BASE_MINIC
=
find_device
(
0xab28633a
);
BASE_EP
=
find_device
(
0x650c2d4f
);
BASE_SOFTPLL
=
find_device
(
0x65158dc0
);
BASE_PPS_GEN
=
find_device
(
0xde0d8ced
);
BASE_SYSCON
=
find_device
(
0xff07fc47
);
BASE_UART
=
find_device
(
0xe2d13d04
);
BASE_ONEWIRE
=
find_device
(
0x779c5443
);
BASE_ETHERBONE_CFG
=
find_device
(
0x68202b22
);
}
sdb-lib/access.c
View file @
9db373ba
...
...
@@ -21,7 +21,7 @@ int sdbfs_fstat(struct sdbfs *fs, struct sdb_device *record_return)
int
sdbfs_fread
(
struct
sdbfs
*
fs
,
int
offset
,
void
*
buf
,
int
count
)
{
int
ret
=
count
;
int
ret
;
if
(
!
fs
->
currentp
)
return
-
ENOENT
;
...
...
@@ -29,6 +29,7 @@ int sdbfs_fread(struct sdbfs *fs, int offset, void *buf, int count)
offset
=
fs
->
read_offset
;
if
(
offset
+
count
>
fs
->
f_len
)
count
=
fs
->
f_len
-
offset
;
ret
=
count
;
if
(
fs
->
data
)
memcpy
(
buf
,
fs
->
data
+
fs
->
f_offset
+
offset
,
count
);
else
...
...
@@ -40,7 +41,7 @@ int sdbfs_fread(struct sdbfs *fs, int offset, void *buf, int count)
int
sdbfs_fwrite
(
struct
sdbfs
*
fs
,
int
offset
,
void
*
buf
,
int
count
)
{
int
ret
=
count
;
int
ret
;
if
(
!
fs
->
currentp
)
return
-
ENOENT
;
...
...
@@ -48,6 +49,7 @@ int sdbfs_fwrite(struct sdbfs *fs, int offset, void *buf, int count)
offset
=
fs
->
read_offset
;
if
(
offset
+
count
>
fs
->
f_len
)
count
=
fs
->
f_len
-
offset
;
ret
=
count
;
if
(
fs
->
data
)
memcpy
(
buf
,
fs
->
data
+
fs
->
f_offset
+
offset
,
count
);
else
...
...
sdb-lib/glue.c
View file @
9db373ba
/*
* Copyright (C) 2012 CERN (www.cern.ch)
* Copyright (C) 2012
,2014
CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
...
...
@@ -14,21 +14,24 @@
static
struct
sdbfs
*
sdbfs_list
;
/* All fields unused by the caller are expected to be zeroed */
int
sdbfs_dev_create
(
struct
sdbfs
*
fs
,
int
verbose
)
int
sdbfs_dev_create
(
struct
sdbfs
*
fs
)
{
unsigned
int
magic
;
/* First, check we have the magic */
if
(
fs
->
data
)
if
(
fs
->
data
||
(
fs
->
flags
&
SDBFS_F_ZEROBASED
)
)
magic
=
*
(
unsigned
int
*
)(
fs
->
data
+
fs
->
entrypoint
);
else
fs
->
read
(
fs
,
fs
->
entrypoint
,
&
magic
,
sizeof
(
magic
));
if
(
htonl
(
magic
)
!=
SDB_MAGIC
)
if
(
magic
==
SDB_MAGIC
)
{
/* Uh! If we are little-endian, we must convert */
if
(
ntohl
(
1
)
!=
1
)
fs
->
flags
|=
SDBFS_F_CONVERT32
;
}
else
if
(
htonl
(
magic
)
==
SDB_MAGIC
)
{
/* ok, don't convert */
}
else
{
return
-
ENOTDIR
;
if
(
verbose
)
fs
->
flags
|=
SDBFS_F_VERBOSE
;
}
fs
->
next
=
sdbfs_list
;
sdbfs_list
=
fs
;
...
...
@@ -70,47 +73,120 @@ static struct sdb_device *sdbfs_readentry(struct sdbfs *fs,
/*
* This function reads an entry from a known good offset. It
* returns the pointer to the entry, which may be stored in
* the fs structure itself. Only touches fs->current_record
* the fs structure itself. Only touches fs->current_record
.
*/
if
(
fs
->
data
)
if
(
fs
->
data
||
(
fs
->
flags
&
SDBFS_F_ZEROBASED
))
{
if
(
!
(
fs
->
flags
&
SDBFS_F_CONVERT32
))
return
(
struct
sdb_device
*
)(
fs
->
data
+
offset
);
/* copy to local storage for conversion */
memcpy
(
&
fs
->
current_record
,
fs
->
data
+
offset
,
sizeof
(
fs
->
current_record
));
}
else
{
if
(
!
fs
->
read
)
return
NULL
;
fs
->
read
(
fs
,
offset
,
&
fs
->
current_record
,
sizeof
(
fs
->
current_record
));
fs
->
read
(
fs
,
offset
,
&
fs
->
current_record
,
sizeof
(
fs
->
current_record
));
}
if
(
fs
->
flags
&
SDBFS_F_CONVERT32
)
{
uint32_t
*
p
=
(
void
*
)
&
fs
->
current_record
;
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
fs
->
current_record
)
/
sizeof
(
*
p
);
i
++
)
p
[
i
]
=
ntohl
(
p
[
i
]);
}
return
&
fs
->
current_record
;
}
/* Helper for scanning: we enter a new directory, and we must validate */
static
struct
sdb_device
*
scan_newdir
(
struct
sdbfs
*
fs
,
int
depth
)
{
struct
sdb_device
*
dev
;
struct
sdb_interconnect
*
intercon
;
dev
=
fs
->
currentp
=
sdbfs_readentry
(
fs
,
fs
->
this
[
depth
]);
if
(
dev
->
sdb_component
.
product
.
record_type
!=
sdb_type_interconnect
)
return
NULL
;
intercon
=
(
typeof
(
intercon
))
dev
;
if
(
ntohl
(
intercon
->
sdb_magic
)
!=
SDB_MAGIC
)
return
NULL
;
fs
->
nleft
[
depth
]
=
ntohs
(
intercon
->
sdb_records
)
-
1
;
fs
->
this
[
depth
]
+=
sizeof
(
*
intercon
);
fs
->
depth
=
depth
;
return
dev
;
}
struct
sdb_device
*
sdbfs_scan
(
struct
sdbfs
*
fs
,
int
newscan
)
{
/*
* This returns a pointer to the next sdb record, or a new one.
* Subdirectories are not supported. Uses all internal fields
* This returns a pointer to the next sdb record, or the first one.
* Subdirectories (bridges) are returned before their contents.
* It only uses internal fields.
*/
struct
sdb_device
*
ret
;
struct
sdb_interconnect
*
i
;
struct
sdb_device
*
dev
;
struct
sdb_bridge
*
bridge
;
int
depth
,
type
,
newdir
=
0
;
/* check there's the magic */
if
(
newscan
)
{
fs
->
f_offset
=
fs
->
entrypoint
;
}
else
{
fs
->
f_offset
+=
sizeof
(
struct
sdb_device
)
;
if
(
!
fs
->
nleft
)
return
NULL
;
fs
->
base
[
0
]
=
0
;
fs
->
this
[
0
]
=
fs
->
entrypoint
;
depth
=
fs
->
depth
=
0
;
newdir
=
1
;
goto
scan
;
}
ret
=
sdbfs_readentry
(
fs
,
fs
->
f_offset
);
if
(
newscan
)
{
i
=
(
typeof
(
i
))
ret
;
fs
->
nleft
=
ntohs
(
i
->
sdb_records
)
-
1
;
}
else
{
fs
->
nleft
--
;
/* If we already returned a bridge, go inside it (check type) */
depth
=
fs
->
depth
;
type
=
fs
->
currentp
->
sdb_component
.
product
.
record_type
;
if
(
type
==
sdb_type_bridge
&&
depth
+
1
<
SDBFS_DEPTH
)
{
bridge
=
(
typeof
(
bridge
))
fs
->
currentp
;
fs
->
this
[
depth
+
1
]
=
fs
->
base
[
depth
]
+
ntohll
(
bridge
->
sdb_child
);
fs
->
base
[
depth
+
1
]
=
fs
->
base
[
depth
]
+
ntohll
(
bridge
->
sdb_component
.
addr_first
);
depth
++
;
newdir
++
;
}
scan:
/* If entering a new directory, verify magic and set nleft */
if
(
newdir
)
{
dev
=
scan_newdir
(
fs
,
depth
);
if
(
dev
)
goto
out
;
/* Otherwise the directory is not there: no intercon */
if
(
!
depth
)
return
NULL
;
/* no entries at all */
depth
--
;
}
return
ret
;
while
(
fs
->
nleft
[
depth
]
==
0
)
{
/* No more at this level, "cd .." if possible */
if
(
!
depth
)
return
NULL
;
fs
->
depth
=
--
depth
;
}
/* so, read the next entry */
dev
=
fs
->
currentp
=
sdbfs_readentry
(
fs
,
fs
->
this
[
depth
]);
fs
->
this
[
depth
]
+=
sizeof
(
*
dev
);
fs
->
nleft
[
depth
]
--
;
out:
fs
->
f_offset
=
fs
->
base
[
fs
->
depth
]
+
htonll
(
fs
->
currentp
->
sdb_component
.
addr_first
);
return
dev
;
}
static
void
__open
(
struct
sdbfs
*
fs
)
{
fs
->
f_offset
=
htonll
(
fs
->
currentp
->
sdb_component
.
addr_first
);
fs
->
f_offset
=
fs
->
base
[
fs
->
depth
]
+
htonll
(
fs
->
currentp
->
sdb_component
.
addr_first
);
fs
->
f_len
=
htonll
(
fs
->
currentp
->
sdb_component
.
addr_last
)
+
1
-
fs
->
f_offset
;
+
1
-
htonll
(
fs
->
currentp
->
sdb_component
.
addr_first
)
;
fs
->
read_offset
=
0
;
}
...
...
@@ -157,3 +233,31 @@ int sdbfs_close(struct sdbfs *fs)
return
0
;
}
/* to "find" a device, open it, get the current offset, then close */
unsigned
long
sdbfs_find_name
(
struct
sdbfs
*
fs
,
const
char
*
name
)
{
unsigned
long
offset
;
int
ret
;
ret
=
sdbfs_open_name
(
fs
,
name
);
if
(
ret
<
0
)
return
(
unsigned
long
)
ret
;
offset
=
fs
->
f_offset
;
sdbfs_close
(
fs
);
return
offset
;
}
unsigned
long
sdbfs_find_id
(
struct
sdbfs
*
fs
,
uint64_t
vid
,
uint32_t
did
)
{
unsigned
long
offset
;
int
ret
;
ret
=
sdbfs_open_id
(
fs
,
vid
,
did
);
if
(
ret
<
0
)
return
(
unsigned
long
)
ret
;
offset
=
fs
->
f_offset
;
sdbfs_close
(
fs
);
return
offset
;
}
sdb-lib/libsdbfs-kernel.h
View file @
9db373ba
/*
* This supports both the Linux kernel and barebox, that is similar
* by design, and defines __KERNEL__ too.
*/
#ifdef __BAREBOX__
# include <errno.h>
#else
/* really linux */
# include <linux/errno.h>
#endif
#include <linux/types.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <asm/byteorder.h>
/*
...
...
@@ -11,8 +19,12 @@
* So, check if we got the information we need before strange errors happen.
* The DECLARE_BITMAP macro is in <linux/types.h> since the epoch, but it
* is not installed in /usr/include/linux/types.h, so use it to check.
*
* If building for barebox, we miss the macro, but we are sure that
* we are picking the correct header, because the library is only built
* within the barebox source tree.
*/
#if
ndef DECLARE_BITMAP
#if
!defined(DECLARE_BITMAP) && !defined(__BAREBOX__)
# error "Please point LINUX to a source tree if you define __KERNEL__"
#endif
...
...
@@ -20,5 +32,4 @@
#define SDB_USER 0
#define SDB_FREESTAND 0
#define sdb_print(format, ...) printk(format, __VA_ARGS__)
sdb-lib/libsdbfs.h
View file @
9db373ba
#ifndef __LIBSDBFS_H__
#define __LIBSDBFS_H__
/* The library can work in
three different environments
*/
/* The library can work in
different environments, take care of them
*/
#ifdef __KERNEL__
# include "libsdbfs-kernel.h"
#elif defined(__unix__)
...
...
@@ -12,6 +12,7 @@
#include <sdb.h>
/* Please point your "-I" to some sensible place */
#define SDBFS_DEPTH 4
/* Max number of subdirectory depth */
/*
* Data structures: please not that the library intself doesn't use
* malloc, so it's the caller who must deal withallocation/removal.
...
...
@@ -24,8 +25,9 @@ struct sdbfs {
/* Some fields are informative */
char
*
name
;
/* may be null */
void
*
drvdata
;
/* driver may need some detail.. */
int
blocksize
;
unsigned
long
blocksize
;
unsigned
long
entrypoint
;
unsigned
long
flags
;
/* The "driver" must offer some methods */
void
*
data
;
/* Use this if directly mapped */
...
...
@@ -35,23 +37,30 @@ struct sdbfs {
int
(
*
erase
)(
struct
sdbfs
*
fs
,
int
offset
,
int
count
);
/* The following fields are library-private */
struct
sdb_device
current_record
;
struct
sdb_device
*
currentp
;
int
nleft
;
unsigned
long
f_offset
;
struct
sdb_device
current_record
;
unsigned
long
f_len
;
unsigned
long
read_offset
;
unsigned
long
flags
;
unsigned
long
f_offset
;
/* start of file */
unsigned
long
read_offset
;
/* current location */
struct
sdbfs
*
next
;
/* The following ones are directory-aware */
unsigned
long
base
[
SDBFS_DEPTH
];
/* for relative addresses */
unsigned
long
this
[
SDBFS_DEPTH
];
/* current sdb record */
int
nleft
[
SDBFS_DEPTH
];
int
depth
;
};
#define SDBFS_F_VERBOSE 0x0001
/* Some flags are set by the user, some (convert32) by the library */
#define SDBFS_F_VERBOSE 0x0001
/* not really used yet */
#define SDBFS_F_CONVERT32 0x0002
/* swap SDB words as they are read */
#define SDBFS_F_ZEROBASED 0x0004
/* zero is a valid data pointer */
/* Defined in glue.c */
int
sdbfs_dev_create
(
struct
sdbfs
*
fs
,
int
verbose
);
int
sdbfs_dev_create
(
struct
sdbfs
*
fs
);
int
sdbfs_dev_destroy
(
struct
sdbfs
*
fs
);
struct
sdbfs
*
sdbfs_dev_find
(
const
char
*
name
);
unsigned
long
sdbfs_find_name
(
struct
sdbfs
*
fs
,
const
char
*
name
);
unsigned
long
sdbfs_find_id
(
struct
sdbfs
*
fs
,
uint64_t
vid
,
uint32_t
did
);
int
sdbfs_open_name
(
struct
sdbfs
*
fs
,
const
char
*
name
);
int
sdbfs_open_id
(
struct
sdbfs
*
fs
,
uint64_t
vid
,
uint32_t
did
);
int
sdbfs_close
(
struct
sdbfs
*
fs
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment