Commit 23813168 authored by David S. Miller's avatar David S. Miller

Merge branch 'ynl-ethtool'

Jakub Kicinski says:

====================
tools: ynl: generate code for the ethtool family

And finally ethtool support. Thanks to Stan's work the ethtool family
spec is quite complete, so there is a lot of operations to support.

I chickened out of stats-get support, they require at the very least
type-value support on a u64 scalar. Type-value is an arrangement where
a u16 attribute is encoded directly in attribute type. Code gen can
support this if the inside is a nest, we just throw in an extra
field into that nest to carry the attr type. But a little more coding
is needed to for a scalar, because first we need to turn the scalar
into a struct with one member, then we can add the attr type.

Other than that ethtool required event support (notification which
does not share contents with any GET), but the previous series
already added that to the codegen.

I haven't tested all the ops here, and a few I tried seem to work.
====================
Acked-by: default avatarStanislav Fomichev <sdf@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b30a1f30 f561ff23
...@@ -195,6 +195,10 @@ properties: ...@@ -195,6 +195,10 @@ properties:
description: Max length for a string or a binary attribute. description: Max length for a string or a binary attribute.
$ref: '#/$defs/len-or-define' $ref: '#/$defs/len-or-define'
sub-type: *attr-type sub-type: *attr-type
# Start genetlink-c
name-prefix:
type: string
# End genetlink-c
# Make sure name-prefix does not appear in subsets (subsets inherit naming) # Make sure name-prefix does not appear in subsets (subsets inherit naming)
dependencies: dependencies:
......
...@@ -226,6 +226,10 @@ properties: ...@@ -226,6 +226,10 @@ properties:
description: Max length for a string or a binary attribute. description: Max length for a string or a binary attribute.
$ref: '#/$defs/len-or-define' $ref: '#/$defs/len-or-define'
sub-type: *attr-type sub-type: *attr-type
# Start genetlink-c
name-prefix:
type: string
# End genetlink-c
# Start genetlink-legacy # Start genetlink-legacy
struct: struct:
description: Name of the struct type used for the attribute. description: Name of the struct type used for the attribute.
......
...@@ -9,8 +9,13 @@ doc: Partial family for Ethtool Netlink. ...@@ -9,8 +9,13 @@ doc: Partial family for Ethtool Netlink.
definitions: definitions:
- -
name: udp-tunnel-type name: udp-tunnel-type
enum-name:
type: enum type: enum
entries: [ vxlan, geneve, vxlan-gpe ] entries: [ vxlan, geneve, vxlan-gpe ]
-
name: stringset
type: enum
entries: []
attribute-sets: attribute-sets:
- -
...@@ -497,7 +502,7 @@ attribute-sets: ...@@ -497,7 +502,7 @@ attribute-sets:
attributes: attributes:
- -
name: pad name: pad
type: u32 type: pad
- -
name: tx-frames name: tx-frames
type: u64 type: u64
...@@ -577,7 +582,7 @@ attribute-sets: ...@@ -577,7 +582,7 @@ attribute-sets:
name: phc-index name: phc-index
type: u32 type: u32
- -
name: cable-test-ntf-nest-result name: cable-result
attributes: attributes:
- -
name: pair name: pair
...@@ -586,7 +591,7 @@ attribute-sets: ...@@ -586,7 +591,7 @@ attribute-sets:
name: code name: code
type: u8 type: u8
- -
name: cable-test-ntf-nest-fault-length name: cable-fault-length
attributes: attributes:
- -
name: pair name: pair
...@@ -595,18 +600,25 @@ attribute-sets: ...@@ -595,18 +600,25 @@ attribute-sets:
name: cm name: cm
type: u32 type: u32
- -
name: cable-test-ntf-nest name: cable-nest
attributes: attributes:
- -
name: result name: result
type: nest type: nest
nested-attributes: cable-test-ntf-nest-result nested-attributes: cable-result
- -
name: fault-length name: fault-length
type: nest type: nest
nested-attributes: cable-test-ntf-nest-fault-length nested-attributes: cable-fault-length
- -
name: cable-test name: cable-test
attributes:
-
name: header
type: nest
nested-attributes: header
-
name: cable-test-ntf
attributes: attributes:
- -
name: header name: header
...@@ -618,7 +630,7 @@ attribute-sets: ...@@ -618,7 +630,7 @@ attribute-sets:
- -
name: nest name: nest
type: nest type: nest
nested-attributes: cable-test-ntf-nest nested-attributes: cable-nest
- -
name: cable-test-tdr-cfg name: cable-test-tdr-cfg
attributes: attributes:
...@@ -632,8 +644,22 @@ attribute-sets: ...@@ -632,8 +644,22 @@ attribute-sets:
name: step name: step
type: u32 type: u32
- -
name: pari name: pair
type: u8 type: u8
-
name: cable-test-tdr-ntf
attributes:
-
name: header
type: nest
nested-attributes: header
-
name: status
type: u8
-
name: nest
type: nest
nested-attributes: cable-nest
- -
name: cable-test-tdr name: cable-test-tdr
attributes: attributes:
...@@ -646,7 +672,7 @@ attribute-sets: ...@@ -646,7 +672,7 @@ attribute-sets:
type: nest type: nest
nested-attributes: cable-test-tdr-cfg nested-attributes: cable-test-tdr-cfg
- -
name: tunnel-info-udp-entry name: tunnel-udp-entry
attributes: attributes:
- -
name: port name: port
...@@ -657,7 +683,7 @@ attribute-sets: ...@@ -657,7 +683,7 @@ attribute-sets:
type: u32 type: u32
enum: udp-tunnel-type enum: udp-tunnel-type
- -
name: tunnel-info-udp-table name: tunnel-udp-table
attributes: attributes:
- -
name: size name: size
...@@ -667,9 +693,17 @@ attribute-sets: ...@@ -667,9 +693,17 @@ attribute-sets:
type: nest type: nest
nested-attributes: bitset nested-attributes: bitset
- -
name: udp-ports name: entry
type: nest type: nest
nested-attributes: tunnel-info-udp-entry multi-attr: true
nested-attributes: tunnel-udp-entry
-
name: tunnel-udp
attributes:
-
name: table
type: nest
nested-attributes: tunnel-udp-table
- -
name: tunnel-info name: tunnel-info
attributes: attributes:
...@@ -680,13 +714,13 @@ attribute-sets: ...@@ -680,13 +714,13 @@ attribute-sets:
- -
name: udp-ports name: udp-ports
type: nest type: nest
nested-attributes: tunnel-info-udp-table nested-attributes: tunnel-udp
- -
name: fec-stat name: fec-stat
attributes: attributes:
- -
name: pad name: pad
type: u8 type: pad
- -
name: corrected name: corrected
type: binary type: binary
...@@ -750,7 +784,7 @@ attribute-sets: ...@@ -750,7 +784,7 @@ attribute-sets:
attributes: attributes:
- -
name: pad name: pad
type: u32 type: pad
- -
name: id name: id
type: u32 type: u32
...@@ -759,16 +793,29 @@ attribute-sets: ...@@ -759,16 +793,29 @@ attribute-sets:
type: u32 type: u32
- -
name: stat name: stat
type: nest type: u64
nested-attributes: u64 type-value: [ id ]
- -
name: hist-rx name: hist-rx
type: nest type: nest
nested-attributes: u64 nested-attributes: stats-grp-hist
- -
name: hist-tx name: hist-tx
type: nest type: nest
nested-attributes: u64 nested-attributes: stats-grp-hist
-
name: hist-bkt-low
type: u32
-
name: hist-bkt-hi
type: u32
-
name: hist-val
type: u64
-
name: stats-grp-hist
subset-of: stats-grp
attributes:
- -
name: hist-bkt-low name: hist-bkt-low
type: u32 type: u32
...@@ -783,7 +830,7 @@ attribute-sets: ...@@ -783,7 +830,7 @@ attribute-sets:
attributes: attributes:
- -
name: pad name: pad
type: u32 type: pad
- -
name: header name: header
type: nest type: nest
...@@ -836,12 +883,15 @@ attribute-sets: ...@@ -836,12 +883,15 @@ attribute-sets:
- -
name: admin-state name: admin-state
type: u32 type: u32
name-prefix: ethtool-a-podl-pse-
- -
name: admin-control name: admin-control
type: u32 type: u32
name-prefix: ethtool-a-podl-pse-
- -
name: pw-d-status name: pw-d-status
type: u32 type: u32
name-prefix: ethtool-a-podl-pse-
- -
name: rss name: rss
attributes: attributes:
...@@ -895,6 +945,7 @@ attribute-sets: ...@@ -895,6 +945,7 @@ attribute-sets:
operations: operations:
enum-model: directional enum-model: directional
name-prefix: ethtool-msg-
list: list:
- -
name: strset-get name: strset-get
...@@ -1348,10 +1399,16 @@ operations: ...@@ -1348,10 +1399,16 @@ operations:
request: request:
attributes: attributes:
- header - header
reply: -
attributes: name: cable-test-ntf
- header doc: Cable test notification.
- cable-test-ntf-nest
attribute-set: cable-test-ntf
event:
attributes:
- header
- status
- -
name: cable-test-tdr-act name: cable-test-tdr-act
doc: Cable test TDR. doc: Cable test TDR.
...@@ -1362,10 +1419,17 @@ operations: ...@@ -1362,10 +1419,17 @@ operations:
request: request:
attributes: attributes:
- header - header
reply: -
attributes: name: cable-test-tdr-ntf
- header doc: Cable test TDR notification.
- cable-test-tdr-cfg
attribute-set: cable-test-tdr-ntf
event:
attributes:
- header
- status
- nest
- -
name: tunnel-info-get name: tunnel-info-get
doc: Get tsinfo params. doc: Get tsinfo params.
......
...@@ -7,9 +7,12 @@ ifeq ("$(DEBUG)","1") ...@@ -7,9 +7,12 @@ ifeq ("$(DEBUG)","1")
CFLAGS += -g -fsanitize=address -fsanitize=leak -static-libasan CFLAGS += -g -fsanitize=address -fsanitize=leak -static-libasan
endif endif
YNL_GEN_ARG_ethtool:=--user-header linux/ethtool_netlink.h \
--exclude-op stats-get
TOOL:=../ynl-gen-c.py TOOL:=../ynl-gen-c.py
GENS:=devlink handshake fou netdev GENS:=ethtool devlink handshake fou netdev
SRCS=$(patsubst %,%-user.c,${GENS}) SRCS=$(patsubst %,%-user.c,${GENS})
HDRS=$(patsubst %,%-user.h,${GENS}) HDRS=$(patsubst %,%-user.h,${GENS})
OBJS=$(patsubst %,%-user.o,${GENS}) OBJS=$(patsubst %,%-user.o,${GENS})
...@@ -22,11 +25,11 @@ protos.a: $(OBJS) ...@@ -22,11 +25,11 @@ protos.a: $(OBJS)
%-user.h: ../../../../Documentation/netlink/specs/%.yaml $(TOOL) %-user.h: ../../../../Documentation/netlink/specs/%.yaml $(TOOL)
@echo -e "\tGEN $@" @echo -e "\tGEN $@"
@$(TOOL) --mode user --header --spec $< > $@ @$(TOOL) --mode user --header --spec $< $(YNL_GEN_ARG_$*) > $@
%-user.c: ../../../../Documentation/netlink/specs/%.yaml $(TOOL) %-user.c: ../../../../Documentation/netlink/specs/%.yaml $(TOOL)
@echo -e "\tGEN $@" @echo -e "\tGEN $@"
@$(TOOL) --mode user --source --spec $< > $@ @$(TOOL) --mode user --source --spec $< $(YNL_GEN_ARG_$*) > $@
%-user.o: %-user.c %-user.h %-user.o: %-user.c %-user.h
@echo -e "\tCC $@" @echo -e "\tCC $@"
......
This diff is collapsed.
This diff is collapsed.
...@@ -334,7 +334,7 @@ class SpecFamily(SpecElement): ...@@ -334,7 +334,7 @@ class SpecFamily(SpecElement):
consts dict of all constants/enums consts dict of all constants/enums
fixed_header string, optional name of family default fixed header struct fixed_header string, optional name of family default fixed header struct
""" """
def __init__(self, spec_path, schema_path=None): def __init__(self, spec_path, schema_path=None, exclude_ops=None):
with open(spec_path, "r") as stream: with open(spec_path, "r") as stream:
prefix = '# SPDX-License-Identifier: ' prefix = '# SPDX-License-Identifier: '
first = stream.readline().strip() first = stream.readline().strip()
...@@ -349,6 +349,8 @@ class SpecFamily(SpecElement): ...@@ -349,6 +349,8 @@ class SpecFamily(SpecElement):
super().__init__(self, spec) super().__init__(self, spec)
self._exclude_ops = exclude_ops if exclude_ops else []
self.proto = self.yaml.get('protocol', 'genetlink') self.proto = self.yaml.get('protocol', 'genetlink')
self.msg_id_model = self.yaml['operations'].get('enum-model', 'unified') self.msg_id_model = self.yaml['operations'].get('enum-model', 'unified')
...@@ -449,7 +451,13 @@ class SpecFamily(SpecElement): ...@@ -449,7 +451,13 @@ class SpecFamily(SpecElement):
req_val = None req_val = None
if rsp_val == rsp_val_next: if rsp_val == rsp_val_next:
rsp_val = None rsp_val = None
op = self.new_operation(elem, req_val, rsp_val)
skip = False
for exclude in self._exclude_ops:
skip |= bool(exclude.match(elem['name']))
if not skip:
op = self.new_operation(elem, req_val, rsp_val)
req_val = req_val_next req_val = req_val_next
rsp_val = rsp_val_next rsp_val = rsp_val_next
......
ethtool
devlink devlink
netdev netdev
// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <string.h>
#include <ynl.h>
#include <net/if.h>
#include "ethtool-user.h"
int main(int argc, char **argv)
{
struct ethtool_channels_get_req_dump creq = {};
struct ethtool_rings_get_req_dump rreq = {};
struct ethtool_channels_get_list *channels;
struct ethtool_rings_get_list *rings;
struct ynl_sock *ys;
ys = ynl_sock_create(&ynl_ethtool_family, NULL);
if (!ys)
return 1;
creq._present.header = 1; /* ethtool needs an empty nest, sigh */
channels = ethtool_channels_get_dump(ys, &creq);
if (!channels)
goto err_close;
printf("Channels:\n");
ynl_dump_foreach(channels, dev) {
printf(" %8s: ", dev->header.dev_name);
if (dev->_present.rx_count)
printf("rx %d ", dev->rx_count);
if (dev->_present.tx_count)
printf("tx %d ", dev->tx_count);
if (dev->_present.combined_count)
printf("combined %d ", dev->combined_count);
printf("\n");
}
ethtool_channels_get_list_free(channels);
rreq._present.header = 1; /* ethtool needs an empty nest.. */
rings = ethtool_rings_get_dump(ys, &rreq);
if (!rings)
goto err_close;
printf("Rings:\n");
ynl_dump_foreach(rings, dev) {
printf(" %8s: ", dev->header.dev_name);
if (dev->_present.rx)
printf("rx %d ", dev->rx);
if (dev->_present.tx)
printf("tx %d ", dev->tx);
printf("\n");
}
ethtool_rings_get_list_free(rings);
ynl_sock_destroy(ys);
return 0;
err_close:
fprintf(stderr, "YNL (%d): %s\n", ys->err.code, ys->err.msg);
ynl_sock_destroy(ys);
return 2;
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import argparse import argparse
import collections import collections
import os import os
import re
import yaml import yaml
from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, SpecEnumEntry from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, SpecEnumEntry
...@@ -48,6 +49,11 @@ class Type(SpecAttr): ...@@ -48,6 +49,11 @@ class Type(SpecAttr):
else: else:
self.nested_render_name = f"{family.name}_{c_lower(self.nested_attrs)}" self.nested_render_name = f"{family.name}_{c_lower(self.nested_attrs)}"
if self.nested_attrs in self.family.consts:
self.nested_struct_type = 'struct ' + self.nested_render_name + '_'
else:
self.nested_struct_type = 'struct ' + self.nested_render_name
self.c_name = c_lower(self.name) self.c_name = c_lower(self.name)
if self.c_name in _C_KW: if self.c_name in _C_KW:
self.c_name += '_' self.c_name += '_'
...@@ -57,8 +63,11 @@ class Type(SpecAttr): ...@@ -57,8 +63,11 @@ class Type(SpecAttr):
delattr(self, "enum_name") delattr(self, "enum_name")
def resolve(self): def resolve(self):
self.enum_name = f"{self.attr_set.name_prefix}{self.name}" if 'name-prefix' in self.attr:
self.enum_name = c_upper(self.enum_name) enum_name = f"{self.attr['name-prefix']}{self.name}"
else:
enum_name = f"{self.attr_set.name_prefix}{self.name}"
self.enum_name = c_upper(enum_name)
def is_multi_val(self): def is_multi_val(self):
return None return None
...@@ -264,7 +273,8 @@ class TypeScalar(Type): ...@@ -264,7 +273,8 @@ class TypeScalar(Type):
else: else:
self.is_bitfield = False self.is_bitfield = False
if 'enum' in self.attr and not self.is_bitfield: maybe_enum = not self.is_bitfield and 'enum' in self.attr
if maybe_enum and self.family.consts[self.attr['enum']].enum_name:
self.type_name = f"enum {self.family.name}_{c_lower(self.attr['enum'])}" self.type_name = f"enum {self.family.name}_{c_lower(self.attr['enum'])}"
else: else:
self.type_name = '__' + self.type self.type_name = '__' + self.type
...@@ -420,7 +430,7 @@ class TypeBinary(Type): ...@@ -420,7 +430,7 @@ class TypeBinary(Type):
class TypeNest(Type): class TypeNest(Type):
def _complex_member_type(self, ri): def _complex_member_type(self, ri):
return f"struct {self.nested_render_name}" return self.nested_struct_type
def free(self, ri, var, ref): def free(self, ri, var, ref):
ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name});') ri.cw.p(f'{self.nested_render_name}_free(&{var}->{ref}{self.c_name});')
...@@ -465,7 +475,7 @@ class TypeMultiAttr(Type): ...@@ -465,7 +475,7 @@ class TypeMultiAttr(Type):
def _complex_member_type(self, ri): def _complex_member_type(self, ri):
if 'type' not in self.attr or self.attr['type'] == 'nest': if 'type' not in self.attr or self.attr['type'] == 'nest':
return f"struct {self.nested_render_name}" return self.nested_struct_type
elif self.attr['type'] in scalars: elif self.attr['type'] in scalars:
scalar_pfx = '__' if ri.ku_space == 'user' else '' scalar_pfx = '__' if ri.ku_space == 'user' else ''
return scalar_pfx + self.attr['type'] return scalar_pfx + self.attr['type']
...@@ -525,7 +535,7 @@ class TypeArrayNest(Type): ...@@ -525,7 +535,7 @@ class TypeArrayNest(Type):
def _complex_member_type(self, ri): def _complex_member_type(self, ri):
if 'sub-type' not in self.attr or self.attr['sub-type'] == 'nest': if 'sub-type' not in self.attr or self.attr['sub-type'] == 'nest':
return f"struct {self.nested_render_name}" return self.nested_struct_type
elif self.attr['sub-type'] in scalars: elif self.attr['sub-type'] in scalars:
scalar_pfx = '__' if ri.ku_space == 'user' else '' scalar_pfx = '__' if ri.ku_space == 'user' else ''
return scalar_pfx + self.attr['sub-type'] return scalar_pfx + self.attr['sub-type']
...@@ -545,7 +555,7 @@ class TypeArrayNest(Type): ...@@ -545,7 +555,7 @@ class TypeArrayNest(Type):
class TypeNestTypeValue(Type): class TypeNestTypeValue(Type):
def _complex_member_type(self, ri): def _complex_member_type(self, ri):
return f"struct {self.nested_render_name}" return self.nested_struct_type
def _attr_typol(self): def _attr_typol(self):
return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, ' return f'.type = YNL_PT_NEST, .nest = &{self.nested_render_name}_nest, '
...@@ -588,6 +598,8 @@ class Struct: ...@@ -588,6 +598,8 @@ class Struct:
else: else:
self.render_name = f"{family.name}_{c_lower(space_name)}" self.render_name = f"{family.name}_{c_lower(space_name)}"
self.struct_name = 'struct ' + self.render_name self.struct_name = 'struct ' + self.render_name
if self.nested and space_name in family.consts:
self.struct_name += '_'
self.ptr_name = self.struct_name + ' *' self.ptr_name = self.struct_name + ' *'
self.request = False self.request = False
...@@ -648,7 +660,14 @@ class EnumEntry(SpecEnumEntry): ...@@ -648,7 +660,14 @@ class EnumEntry(SpecEnumEntry):
class EnumSet(SpecEnumSet): class EnumSet(SpecEnumSet):
def __init__(self, family, yaml): def __init__(self, family, yaml):
self.render_name = c_lower(family.name + '-' + yaml['name']) self.render_name = c_lower(family.name + '-' + yaml['name'])
self.enum_name = 'enum ' + self.render_name
if 'enum-name' in yaml:
if yaml['enum-name']:
self.enum_name = 'enum ' + c_lower(yaml['enum-name'])
else:
self.enum_name = None
else:
self.enum_name = 'enum ' + self.render_name
self.value_pfx = yaml.get('name-prefix', f"{family.name}-{yaml['name']}-") self.value_pfx = yaml.get('name-prefix', f"{family.name}-{yaml['name']}-")
...@@ -739,7 +758,7 @@ class Operation(SpecOperation): ...@@ -739,7 +758,7 @@ class Operation(SpecOperation):
class Family(SpecFamily): class Family(SpecFamily):
def __init__(self, file_name): def __init__(self, file_name, exclude_ops):
# Added by resolve: # Added by resolve:
self.c_name = None self.c_name = None
delattr(self, "c_name") delattr(self, "c_name")
...@@ -754,7 +773,7 @@ class Family(SpecFamily): ...@@ -754,7 +773,7 @@ class Family(SpecFamily):
self.hooks = None self.hooks = None
delattr(self, "hooks") delattr(self, "hooks")
super().__init__(file_name) super().__init__(file_name, exclude_ops=exclude_ops)
self.fam_key = c_upper(self.yaml.get('c-family-name', self.yaml["name"] + '_FAMILY_NAME')) self.fam_key = c_upper(self.yaml.get('c-family-name', self.yaml["name"] + '_FAMILY_NAME'))
self.ver_key = c_upper(self.yaml.get('c-version-name', self.yaml["name"] + '_FAMILY_VERSION')) self.ver_key = c_upper(self.yaml.get('c-version-name', self.yaml["name"] + '_FAMILY_VERSION'))
...@@ -982,10 +1001,13 @@ class RenderInfo: ...@@ -982,10 +1001,13 @@ class RenderInfo:
if not self.attr_set: if not self.attr_set:
self.attr_set = op['attribute-set'] self.attr_set = op['attribute-set']
self.type_name_conflict = False
if op: if op:
self.type_name = c_lower(op.name) self.type_name = c_lower(op.name)
else: else:
self.type_name = c_lower(attr_set) self.type_name = c_lower(attr_set)
if attr_set in family.consts:
self.type_name_conflict = True
self.cw = cw self.cw = cw
...@@ -1622,12 +1644,17 @@ def print_alloc_wrapper(ri, direction): ...@@ -1622,12 +1644,17 @@ def print_alloc_wrapper(ri, direction):
def print_free_prototype(ri, direction, suffix=';'): def print_free_prototype(ri, direction, suffix=';'):
name = op_prefix(ri, direction) name = op_prefix(ri, direction)
struct_name = name
if ri.type_name_conflict:
struct_name += '_'
arg = free_arg_name(direction) arg = free_arg_name(direction)
ri.cw.write_func_prot('void', f"{name}_free", [f"struct {name} *{arg}"], suffix=suffix) ri.cw.write_func_prot('void', f"{name}_free", [f"struct {struct_name} *{arg}"], suffix=suffix)
def _print_type(ri, direction, struct): def _print_type(ri, direction, struct):
suffix = f'_{ri.type_name}{direction_to_suffix[direction]}' suffix = f'_{ri.type_name}{direction_to_suffix[direction]}'
if not direction and ri.type_name_conflict:
suffix += '_'
if ri.op_mode == 'dump': if ri.op_mode == 'dump':
suffix += '_dump' suffix += '_dump'
...@@ -2241,6 +2268,7 @@ def main(): ...@@ -2241,6 +2268,7 @@ def main():
parser.add_argument('--header', dest='header', action='store_true', default=None) parser.add_argument('--header', dest='header', action='store_true', default=None)
parser.add_argument('--source', dest='header', action='store_false') parser.add_argument('--source', dest='header', action='store_false')
parser.add_argument('--user-header', nargs='+', default=[]) parser.add_argument('--user-header', nargs='+', default=[])
parser.add_argument('--exclude-op', action='append', default=[])
parser.add_argument('-o', dest='out_file', type=str) parser.add_argument('-o', dest='out_file', type=str)
args = parser.parse_args() args = parser.parse_args()
...@@ -2249,8 +2277,10 @@ def main(): ...@@ -2249,8 +2277,10 @@ def main():
if args.header is None: if args.header is None:
parser.error("--header or --source is required") parser.error("--header or --source is required")
exclude_ops = [re.compile(expr) for expr in args.exclude_op]
try: try:
parsed = Family(args.spec) parsed = Family(args.spec, exclude_ops)
if parsed.license != '((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)': if parsed.license != '((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)':
print('Spec license:', parsed.license) print('Spec license:', parsed.license)
print('License must be: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)') print('License must be: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)')
...@@ -2277,6 +2307,11 @@ def main(): ...@@ -2277,6 +2307,11 @@ def main():
cw.p("/* Do not edit directly, auto-generated from: */") cw.p("/* Do not edit directly, auto-generated from: */")
cw.p(f"/*\t{spec_kernel} */") cw.p(f"/*\t{spec_kernel} */")
cw.p(f"/* YNL-GEN {args.mode} {'header' if args.header else 'source'} */") cw.p(f"/* YNL-GEN {args.mode} {'header' if args.header else 'source'} */")
if args.exclude_op or args.user_header:
line = ''
line += ' --user-header '.join([''] + args.user_header)
line += ' --exclude-op '.join([''] + args.exclude_op)
cw.p(f'/* YNL-ARG{line} */')
cw.nl() cw.nl()
if args.mode == 'uapi': if args.mode == 'uapi':
......
...@@ -19,6 +19,7 @@ for f in $files; do ...@@ -19,6 +19,7 @@ for f in $files; do
# params: 0 1 2 3 # params: 0 1 2 3
# $YAML YNL-GEN kernel $mode # $YAML YNL-GEN kernel $mode
params=( $(git grep -B1 -h '/\* YNL-GEN' $f | sed 's@/\*\(.*\)\*/@\1@') ) params=( $(git grep -B1 -h '/\* YNL-GEN' $f | sed 's@/\*\(.*\)\*/@\1@') )
args=$(sed -n 's@/\* YNL-ARG \(.*\) \*/@\1@p' $f)
if [ $f -nt ${params[0]} -a -z "$force" ]; then if [ $f -nt ${params[0]} -a -z "$force" ]; then
echo -e "\tSKIP $f" echo -e "\tSKIP $f"
...@@ -26,5 +27,6 @@ for f in $files; do ...@@ -26,5 +27,6 @@ for f in $files; do
fi fi
echo -e "\tGEN ${params[2]}\t$f" echo -e "\tGEN ${params[2]}\t$f"
$TOOL --mode ${params[2]} --${params[3]} --spec $KDIR/${params[0]} -o $f $TOOL --mode ${params[2]} --${params[3]} --spec $KDIR/${params[0]} \
$args -o $f
done done
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment