mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 14:12:07 +02:00
ynl: support directional specs in ynl-gen-c.py
The intent is to generate ethtool uapi headers. For now, some of the
things are hard-coded:
- <FAMILY>_MSG_{USER,KERNEL}_MAX
- the split between USER and KERNEL messages
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20241204155549.641348-4-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
8c843ecde4
commit
56881d07f0
|
|
@ -2419,6 +2419,87 @@ def uapi_enum_start(family, cw, obj, ckey='', enum_name='enum-name'):
|
|||
cw.block_start(line=start_line)
|
||||
|
||||
|
||||
def render_uapi_unified(family, cw, max_by_define, separate_ntf):
|
||||
max_name = c_upper(family.get('cmd-max-name', f"{family.op_prefix}MAX"))
|
||||
cnt_name = c_upper(family.get('cmd-cnt-name', f"__{family.op_prefix}MAX"))
|
||||
max_value = f"({cnt_name} - 1)"
|
||||
|
||||
uapi_enum_start(family, cw, family['operations'], 'enum-name')
|
||||
val = 0
|
||||
for op in family.msgs.values():
|
||||
if separate_ntf and ('notify' in op or 'event' in op):
|
||||
continue
|
||||
|
||||
suffix = ','
|
||||
if op.value != val:
|
||||
suffix = f" = {op.value},"
|
||||
val = op.value
|
||||
cw.p(op.enum_name + suffix)
|
||||
val += 1
|
||||
cw.nl()
|
||||
cw.p(cnt_name + ('' if max_by_define else ','))
|
||||
if not max_by_define:
|
||||
cw.p(f"{max_name} = {max_value}")
|
||||
cw.block_end(line=';')
|
||||
if max_by_define:
|
||||
cw.p(f"#define {max_name} {max_value}")
|
||||
cw.nl()
|
||||
|
||||
|
||||
def render_uapi_directional(family, cw, max_by_define):
|
||||
max_name = f"{family.op_prefix}USER_MAX"
|
||||
cnt_name = f"__{family.op_prefix}USER_CNT"
|
||||
max_value = f"({cnt_name} - 1)"
|
||||
|
||||
cw.block_start(line='enum')
|
||||
cw.p(c_upper(f'{family.name}_MSG_USER_NONE = 0,'))
|
||||
val = 0
|
||||
for op in family.msgs.values():
|
||||
if 'do' in op and 'event' not in op:
|
||||
suffix = ','
|
||||
if op.value and op.value != val:
|
||||
suffix = f" = {op.value},"
|
||||
val = op.value
|
||||
cw.p(op.enum_name + suffix)
|
||||
val += 1
|
||||
cw.nl()
|
||||
cw.p(cnt_name + ('' if max_by_define else ','))
|
||||
if not max_by_define:
|
||||
cw.p(f"{max_name} = {max_value}")
|
||||
cw.block_end(line=';')
|
||||
if max_by_define:
|
||||
cw.p(f"#define {max_name} {max_value}")
|
||||
cw.nl()
|
||||
|
||||
max_name = f"{family.op_prefix}KERNEL_MAX"
|
||||
cnt_name = f"__{family.op_prefix}KERNEL_CNT"
|
||||
max_value = f"({cnt_name} - 1)"
|
||||
|
||||
cw.block_start(line='enum')
|
||||
cw.p(c_upper(f'{family.name}_MSG_KERNEL_NONE = 0,'))
|
||||
val = 0
|
||||
for op in family.msgs.values():
|
||||
if ('do' in op and 'reply' in op['do']) or 'notify' in op or 'event' in op:
|
||||
enum_name = op.enum_name
|
||||
if 'event' not in op and 'notify' not in op:
|
||||
enum_name = f'{enum_name}_REPLY'
|
||||
|
||||
suffix = ','
|
||||
if op.value and op.value != val:
|
||||
suffix = f" = {op.value},"
|
||||
val = op.value
|
||||
cw.p(enum_name + suffix)
|
||||
val += 1
|
||||
cw.nl()
|
||||
cw.p(cnt_name + ('' if max_by_define else ','))
|
||||
if not max_by_define:
|
||||
cw.p(f"{max_name} = {max_value}")
|
||||
cw.block_end(line=';')
|
||||
if max_by_define:
|
||||
cw.p(f"#define {max_name} {max_value}")
|
||||
cw.nl()
|
||||
|
||||
|
||||
def render_uapi(family, cw):
|
||||
hdr_prot = f"_UAPI_LINUX_{c_upper(family.uapi_header_name)}_H"
|
||||
hdr_prot = hdr_prot.replace('/', '_')
|
||||
|
|
@ -2523,30 +2604,12 @@ def render_uapi(family, cw):
|
|||
# Commands
|
||||
separate_ntf = 'async-prefix' in family['operations']
|
||||
|
||||
max_name = c_upper(family.get('cmd-max-name', f"{family.op_prefix}MAX"))
|
||||
cnt_name = c_upper(family.get('cmd-cnt-name', f"__{family.op_prefix}MAX"))
|
||||
max_value = f"({cnt_name} - 1)"
|
||||
|
||||
uapi_enum_start(family, cw, family['operations'], 'enum-name')
|
||||
val = 0
|
||||
for op in family.msgs.values():
|
||||
if separate_ntf and ('notify' in op or 'event' in op):
|
||||
continue
|
||||
|
||||
suffix = ','
|
||||
if op.value != val:
|
||||
suffix = f" = {op.value},"
|
||||
val = op.value
|
||||
cw.p(op.enum_name + suffix)
|
||||
val += 1
|
||||
cw.nl()
|
||||
cw.p(cnt_name + ('' if max_by_define else ','))
|
||||
if not max_by_define:
|
||||
cw.p(f"{max_name} = {max_value}")
|
||||
cw.block_end(line=';')
|
||||
if max_by_define:
|
||||
cw.p(f"#define {max_name} {max_value}")
|
||||
cw.nl()
|
||||
if family.msg_id_model == 'unified':
|
||||
render_uapi_unified(family, cw, max_by_define, separate_ntf)
|
||||
elif family.msg_id_model == 'directional':
|
||||
render_uapi_directional(family, cw, max_by_define)
|
||||
else:
|
||||
raise Exception(f'Unsupported message enum-model {family.msg_id_model}')
|
||||
|
||||
if separate_ntf:
|
||||
uapi_enum_start(family, cw, family['operations'], enum_name='async-enum')
|
||||
|
|
@ -2670,13 +2733,6 @@ def main():
|
|||
os.sys.exit(1)
|
||||
return
|
||||
|
||||
supported_models = ['unified']
|
||||
if args.mode in ['user', 'kernel']:
|
||||
supported_models += ['directional']
|
||||
if parsed.msg_id_model not in supported_models:
|
||||
print(f'Message enum-model {parsed.msg_id_model} not supported for {args.mode} generation')
|
||||
os.sys.exit(1)
|
||||
|
||||
cw = CodeWriter(BaseNlLib(), args.out_file, overwrite=(not args.cmp_out))
|
||||
|
||||
_, spec_kernel = find_kernel_root(args.spec)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user