]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[settings] Add "busdevfn" setting type
authorMichael Brown <mcb30@ipxe.org>
Fri, 12 Jul 2013 20:28:00 +0000 (22:28 +0200)
committerMichael Brown <mcb30@ipxe.org>
Fri, 12 Jul 2013 20:38:19 +0000 (22:38 +0200)
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>
src/core/settings.c
src/include/ipxe/settings.h
src/tests/settings_test.c

index b8833c8d5bba72ce7f79fda9e3e52d49aa0aabe5..927ad84590b88761fe77f1bbb056e0d2347916c8 100644 (file)
@@ -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
index 7ceb55ca54e7ce7eb8e8d46b6039cd472b69ff96..8ee9516ecbcc90c4deb718c2bc24e4707dfd5cbc 100644 (file)
@@ -324,6 +324,7 @@ extern struct setting_type setting_type_hex __setting_type;
 extern struct setting_type setting_type_hexhyp __setting_type;
 extern struct setting_type setting_type_hexraw __setting_type;
 extern struct setting_type setting_type_uuid __setting_type;
+extern struct setting_type setting_type_busdevfn __setting_type;
 
 extern struct setting ip_setting __setting ( SETTING_IPv4 );
 extern struct setting netmask_setting __setting ( SETTING_IPv4 );
index d6d1257486773d981ab0ae200cfb4b9578158894..42957c7d77d3384247a8582a4f2f18260b91998c 100644 (file)
@@ -182,6 +182,12 @@ static struct setting test_uuid_setting = {
        .type = &setting_type_uuid,
 };
 
+/** Test PCI bus:dev.fn setting type */
+static struct setting test_busdevfn_setting = {
+       .name = "test_busdevfn",
+       .type = &setting_type_busdevfn,
+};
+
 /**
  * Perform settings self-tests
  *
@@ -282,6 +288,10 @@ static void settings_test_exec ( void ) {
                          0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ),
                    "1a6a749d-0eda-461a-a87a-7cfe4fca4a57" );
 
+       /* "busdevfn" setting type (no store capability) */
+       fetchf_ok ( &test_settings, &test_busdevfn_setting,
+                   RAW ( 0x03, 0x45 ), "03:08.5" );
+
        /* Clear and unregister test settings block */
        clear_settings ( &test_settings );
        unregister_settings ( &test_settings );