diff options
author | Michael Brown | 2013-07-12 22:28:00 +0200 |
---|---|---|
committer | Michael Brown | 2013-07-12 22:38:19 +0200 |
commit | 3dbcce51eaa3de66c945628676d9303aca5a98fd (patch) | |
tree | f45fe0eb90208425f68b14e72bd7cf2981be3027 /src/core/settings.c | |
parent | [netdevice] Add "bustype" and "busloc" settings (diff) | |
download | ipxe-3dbcce51eaa3de66c945628676d9303aca5a98fd.tar.gz ipxe-3dbcce51eaa3de66c945628676d9303aca5a98fd.tar.xz ipxe-3dbcce51eaa3de66c945628676d9303aca5a98fd.zip |
[settings] Add "busdevfn" setting type
Allow network device's "busloc" setting to be formatted as a PCI
bus:dev.fn address using e.g. ${net0/busloc:busdevfn}.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/core/settings.c')
-rw-r--r-- | src/core/settings.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/core/settings.c b/src/core/settings.c index b8833c8d..927ad845 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/uuid.h> #include <ipxe/uri.h> #include <ipxe/base16.h> +#include <ipxe/pci.h> #include <ipxe/init.h> #include <ipxe/settings.h> @@ -1857,6 +1858,52 @@ struct setting_type setting_type_uuid __setting_type = { .format = format_uuid_setting, }; +/** + * Parse PCI bus:dev.fn setting value + * + * @v value Formatted setting value + * @v buf Buffer to contain raw value + * @v len Length of buffer + * @ret len Length of raw value, or negative error + */ +static int parse_busdevfn_setting ( const char *value __unused, + void *buf __unused, size_t len __unused ) { + return -ENOTSUP; +} + +/** + * Format PCI bus:dev.fn setting value + * + * @v raw Raw setting value + * @v raw_len Length of raw setting value + * @v buf Buffer to contain formatted value + * @v len Length of buffer + * @ret len Length of formatted value, or negative error + */ +static int format_busdevfn_setting ( const void *raw, size_t raw_len, char *buf, + size_t len ) { + signed long dummy; + unsigned long busdevfn; + int check_len; + + /* Extract numeric value */ + check_len = numeric_setting_value ( raw, raw_len, &dummy, &busdevfn ); + if ( check_len < 0 ) + return check_len; + assert ( check_len == ( int ) raw_len ); + + /* Format value */ + return snprintf ( buf, len, "%02lx:%02lx.%lx", PCI_BUS ( busdevfn ), + PCI_SLOT ( busdevfn ), PCI_FUNC ( busdevfn ) ); +} + +/** PCI bus:dev.fn setting type */ +struct setting_type setting_type_busdevfn __setting_type = { + .name = "busdevfn", + .parse = parse_busdevfn_setting, + .format = format_busdevfn_setting, +}; + /****************************************************************************** * * Setting expansion |