ID Workflow Result Correct Bug Created Started Finished Revision Error
9087164f patching memory leak in try_get_usb_function_instance 2026/07/30 14:12 2026/07/30 14:12 2026/07/30 15:11 c87b8ba9

			
		
Agent: prod-syz-agent-3
External Bug ID: ---

Inputs:
BaseBranch master
BaseCommit RC
BaseRepository git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
BugTitle memory leak in try_get_usb_function_instance
CrashLogID 6256464068345856
CrashReportID 5274661035704320
KernelCommit 3dab139d4795f688e4f243e40c7474df00d329d9
KernelConfig
Show (278258 bytes)
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 syzkaller Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc (Debian 14.2.0-19) 14.2.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=140200
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=24400
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=24400
CONFIG_LLD_VERSION=0
CONFIG_RUSTC_VERSION=109600
CONFIG_RUST_IS_AVAILABLE=y
CONFIG_RUSTC_LLVM_VERSION=220102
CONFIG_RUSTC_LLVM_MAJOR_VERSION=22
CONFIG_CC_CAN_LINK=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
CONFIG_TOOLS_SUPPORT_RELR=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_ASSUME=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_LD_CAN_USE_KEEP_IN_OVERLAY=y
CONFIG_RUSTC_HAS_SPAN_FILE=y
CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES=y
CONFIG_RUSTC_HAS_FILE_WITH_NUL=y
CONFIG_RUSTC_HAS_FILE_AS_C_STR=y
CONFIG_PAHOLE_VERSION=130
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y

#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
# CONFIG_COMPILE_TEST is not set
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_HAVE_KERNEL_ZSTD=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
# CONFIG_KERNEL_ZSTD is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_WATCH_QUEUE=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_AUDIT=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
CONFIG_GENERIC_IRQ_RESERVATION_MODE=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
# CONFIG_GENERIC_IRQ_DEBUGFS is not set
# end of IRQ subsystem

CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_ARCH_CLOCKSOURCE_INIT=y
CONFIG_ARCH_WANTS_CLOCKSOURCE_READ_INLINE=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST_IDLE=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CLOCKEVENTS_COUPLED=y
CONFIG_GENERIC_CLOCKEVENTS_COUPLED_INLINE=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_HRTIMER_REARM_DEFERRED=y
CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
# CONFIG_NO_HZ_FULL is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_POSIX_AUX_CLOCKS=y
# end of Timers subsystem

CONFIG_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y

#
# BPF subsystem
#
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_BPF_JIT_DEFAULT_ON=y
# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set
CONFIG_BPF_PRELOAD=y
CONFIG_BPF_PRELOAD_UMD=y
CONFIG_BPF_LSM=y
# end of BPF subsystem

CONFIG_PREEMPT_BUILD=y
CONFIG_ARCH_HAS_PREEMPT_LAZY=y
CONFIG_PREEMPT=y
# CONFIG_PREEMPT_LAZY is not set
# CONFIG_PREEMPT_RT is not set
CONFIG_PREEMPT_COUNT=y
CONFIG_PREEMPTION=y
CONFIG_PREEMPT_DYNAMIC=y
CONFIG_SCHED_CORE=y

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_SCHED_AVG_IRQ=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_PSI=y
# CONFIG_PSI_DEFAULT_DISABLED is not set
# end of CPU/Task time and stats accounting

CONFIG_CPU_ISOLATION=y

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
CONFIG_PREEMPT_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_TREE_SRCU=y
CONFIG_TASKS_RCU_GENERIC=y
CONFIG_NEED_TASKS_RCU=y
CONFIG_TASKS_RCU=y
CONFIG_TASKS_TRACE_RCU=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_NEED_SEGCBLIST=y
# end of RCU Subsystem

CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_IKHEADERS is not set
CONFIG_LOG_BUF_SHIFT=18
CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
# CONFIG_PRINTK_INDEX is not set
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y

#
# Scheduler features
#
# CONFIG_UCLAMP_TASK is not set
# CONFIG_SCHED_PROXY_EXEC is not set
# end of Scheduler features

CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
CONFIG_CC_HAS_INT128=y
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_CC_MS_EXTENSIONS="-fms-extensions"
CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_CC_NO_ARRAY_BOUNDS=y
CONFIG_GCC_NO_STRINGOP_OVERFLOW=y
CONFIG_CC_NO_STRINGOP_OVERFLOW=y
CONFIG_ARCH_SUPPORTS_INT128=y
CONFIG_NUMA_BALANCING=y
CONFIG_SCHED_CACHE=y
CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y
CONFIG_SLAB_OBJ_EXT=y
CONFIG_CGROUPS=y
CONFIG_PAGE_COUNTER=y
# CONFIG_CGROUP_FAVOR_DYNMODS is not set
CONFIG_MEMCG=y
CONFIG_MEMCG_V1=y
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_GROUP_SCHED_WEIGHT=y
CONFIG_GROUP_SCHED_BANDWIDTH=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_SCHED_MM_CID=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
# CONFIG_CGROUP_DMEM is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CPUSETS=y
# CONFIG_CPUSETS_V1 is not set
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
# CONFIG_CGROUP_BPF is not set
CONFIG_CGROUP_MISC=y
CONFIG_CGROUP_DEBUG=y
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_TIME_NS=y
CONFIG_TIME_NS_VDSO=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_CHECKPOINT_RESTORE=y
# CONFIG_SCHED_AUTOGROUP is not set
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y
CONFIG_RD_ZSTD=y
# CONFIG_BOOT_CONFIG is not set
CONFIG_CMDLINE_LOG_WRAP_IDEAL_LEN=1021
CONFIG_INITRAMFS_PRESERVE_MTIME=y
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_LD_ORPHAN_WARN=y
CONFIG_LD_ORPHAN_WARN_LEVEL="warn"
CONFIG_SYSCTL=y
CONFIG_HAVE_UID16=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYSFS_SYSCALL=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
CONFIG_EXPERT=y
CONFIG_UID16=y
CONFIG_MULTIUSER=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
# CONFIG_BASE_SMALL is not set
CONFIG_FUTEX=y
CONFIG_FUTEX_PI=y
CONFIG_FUTEX_PRIVATE_HASH=y
CONFIG_FUTEX_MPOL=y
CONFIG_HAVE_FUTEX_ROBUST_UNLOCK=y
CONFIG_FUTEX_ROBUST_UNLOCK=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_IO_URING=y
CONFIG_IO_URING_MOCK_FILE=y
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KCMP=y
CONFIG_RSEQ=y
CONFIG_RSEQ_SLICE_EXTENSION=y
# CONFIG_RSEQ_STATS is not set
# CONFIG_RSEQ_DEBUG_DEFAULT_ENABLE is not set
CONFIG_CACHESTAT_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_SELFTEST is not set
CONFIG_KALLSYMS_ALL=y
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
CONFIG_ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_GUEST_PERF_EVENTS=y
CONFIG_PERF_GUEST_MEDIATED_PMU=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
# end of Kernel Performance Events And Counters

CONFIG_SYSTEM_DATA_VERIFICATION=y
CONFIG_PROFILING=y
# CONFIG_RUST is not set
CONFIG_TRACEPOINTS=y

#
# Kexec and crash features
#
CONFIG_CRASH_RESERVE=y
CONFIG_VMCORE_INFO=y
CONFIG_KEXEC_CORE=y
CONFIG_KEXEC=y
# CONFIG_KEXEC_FILE is not set
# CONFIG_KEXEC_JUMP is not set
CONFIG_CRASH_DUMP=y
CONFIG_CRASH_HOTPLUG=y
CONFIG_CRASH_MAX_MEMORY_RANGES=8192
# end of Kexec and crash features

#
# Live Update and Kexec HandOver
#
# CONFIG_KEXEC_HANDOVER is not set
# end of Live Update and Kexec HandOver
# end of General setup

CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_MMU=y
CONFIG_ARCH_MMAP_RND_BITS_MIN=28
CONFIG_ARCH_MMAP_RND_BITS_MAX=32
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_AUDIT_ARCH=y
CONFIG_HAVE_INTEL_TXT=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_PGTABLE_LEVELS=5

#
# Processor type and features
#
CONFIG_SMP=y
CONFIG_X86_X2APIC=y
# CONFIG_X86_POSTED_MSI is not set
CONFIG_X86_MPPARSE=y
# CONFIG_X86_CPU_RESCTRL is not set
CONFIG_X86_FRED=y
CONFIG_X86_EXTENDED_PLATFORM=y
# CONFIG_X86_NUMACHIP is not set
# CONFIG_X86_VSMP is not set
# CONFIG_X86_INTEL_MID is not set
# CONFIG_X86_GOLDFISH is not set
# CONFIG_X86_INTEL_LPSS is not set
# CONFIG_X86_AMD_PLATFORM_DEVICE is not set
CONFIG_IOSF_MBI=y
# CONFIG_IOSF_MBI_DEBUG is not set
CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_HYPERVISOR_GUEST=y
CONFIG_PARAVIRT=y
CONFIG_PARAVIRT_SPINLOCKS=y
CONFIG_X86_HV_CALLBACK_VECTOR=y
# CONFIG_XEN is not set
CONFIG_KVM_GUEST=y
CONFIG_ARCH_CPUIDLE_HALTPOLL=y
CONFIG_PVH=y
# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
CONFIG_PARAVIRT_CLOCK=y
# CONFIG_JAILHOUSE_GUEST is not set
# CONFIG_ACRN_GUEST is not set
# CONFIG_BHYVE_GUEST is not set
CONFIG_CC_HAS_MARCH_NATIVE=y
# CONFIG_X86_NATIVE_CPU is not set
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_TSC=y
CONFIG_X86_HAVE_PAE=y
CONFIG_X86_CX8=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_IA32_FEAT_CTL=y
CONFIG_X86_VMX_FEATURE_NAMES=y
CONFIG_PROCESSOR_SELECT=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
# CONFIG_CPU_SUP_HYGON is not set
# CONFIG_CPU_SUP_CENTAUR is not set
# CONFIG_CPU_SUP_ZHAOXIN is not set
CONFIG_BROADCAST_TLB_FLUSH=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
CONFIG_DMI=y
# CONFIG_GART_IOMMU is not set
CONFIG_BOOT_VESA_SUPPORT=y
# CONFIG_MAXSMP is not set
CONFIG_NR_CPUS_RANGE_BEGIN=2
CONFIG_NR_CPUS_RANGE_END=512
CONFIG_NR_CPUS_DEFAULT=64
CONFIG_NR_CPUS=8
CONFIG_SCHED_MC_PRIO=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_ACPI_MADT_WAKEUP=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y
CONFIG_X86_MCE=y
# CONFIG_X86_MCELOG_LEGACY is not set
CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y
CONFIG_X86_MCE_THRESHOLD=y
# CONFIG_X86_MCE_INJECT is not set

#
# Performance monitoring
#
CONFIG_PERF_EVENTS_INTEL_UNCORE=y
CONFIG_PERF_EVENTS_INTEL_RAPL=y
CONFIG_PERF_EVENTS_INTEL_CSTATE=y
# CONFIG_PERF_EVENTS_AMD_POWER is not set
CONFIG_PERF_EVENTS_AMD_UNCORE=y
# CONFIG_PERF_EVENTS_AMD_BRS is not set
# end of Performance monitoring

CONFIG_X86_16BIT=y
CONFIG_X86_ESPFIX64=y
CONFIG_X86_VSYSCALL_EMULATION=y
CONFIG_X86_IOPL_IOPERM=y
CONFIG_MICROCODE=y
# CONFIG_MICROCODE_LATE_LOADING is not set
# CONFIG_MICROCODE_DBG is not set
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
CONFIG_X86_DIRECT_GBPAGES=y
# CONFIG_X86_CPA_STATISTICS is not set
CONFIG_NUMA=y
CONFIG_AMD_NUMA=y
CONFIG_X86_64_ACPI_NUMA=y
CONFIG_NODES_SHIFT=6
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
# CONFIG_ARCH_MEMORY_PROBE is not set
CONFIG_ARCH_PROC_KCORE_TEXT=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
# CONFIG_X86_PMEM_LEGACY is not set
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
CONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set
CONFIG_X86_PAT=y
CONFIG_X86_UMIP=y
CONFIG_CC_HAS_IBT=y
CONFIG_X86_CET=y
CONFIG_X86_KERNEL_IBT=y
CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y
CONFIG_ARCH_PKEY_BITS=4
# CONFIG_X86_INTEL_TSX_MODE_OFF is not set
CONFIG_X86_INTEL_TSX_MODE_ON=y
# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set
CONFIG_X86_SGX=y
CONFIG_X86_USER_SHADOW_STACK=y
# CONFIG_INTEL_TDX_HOST is not set
# CONFIG_EFI is not set
CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
CONFIG_SCHED_HRTICK=y
CONFIG_ARCH_SUPPORTS_KEXEC=y
CONFIG_ARCH_SUPPORTS_KEXEC_FILE=y
CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY=y
CONFIG_ARCH_SUPPORTS_KEXEC_SIG=y
CONFIG_ARCH_SUPPORTS_KEXEC_SIG_FORCE=y
CONFIG_ARCH_SUPPORTS_KEXEC_BZIMAGE_VERIFY_SIG=y
CONFIG_ARCH_SUPPORTS_KEXEC_JUMP=y
CONFIG_ARCH_SUPPORTS_KEXEC_HANDOVER=y
CONFIG_ARCH_SUPPORTS_CRASH_DUMP=y
CONFIG_ARCH_DEFAULT_CRASH_DUMP=y
CONFIG_ARCH_SUPPORTS_CRASH_HOTPLUG=y
CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION=y
CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x200000
CONFIG_HOTPLUG_CPU=y
# CONFIG_COMPAT_VDSO is not set
CONFIG_LEGACY_VSYSCALL_XONLY=y
# CONFIG_LEGACY_VSYSCALL_NONE is not set
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="earlyprintk=serial net.ifnames=0 sysctl.kernel.hung_task_all_cpu_backtrace=1 ima_policy=tcb nf-conntrack-ftp.ports=20000 nf-conntrack-tftp.ports=20000 nf-conntrack-sip.ports=20000 nf-conntrack-irc.ports=20000 nf-conntrack-sane.ports=20000 binder.debug_mask=0 rcupdate.rcu_expedited=1 rcupdate.rcu_cpu_stall_cputime=1 no_hash_pointers page_owner=on sysctl.vm.nr_hugepages=4 sysctl.vm.nr_overcommit_hugepages=4 secretmem.enable=1 sysctl.max_rcu_stall_to_panic=1 msr.allow_writes=off coredump_filter=0xffff root=/dev/sda console=ttyS0 vsyscall=native numa=fake=2 kvm-intel.nested=1 spec_store_bypass_disable=prctl nopcid vivid.n_devs=64 vivid.multiplanar=1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2 netrom.nr_ndevs=32 rose.rose_ndevs=32 smp.csd_lock_timeout=100000 watchdog_thresh=55 workqueue.watchdog_thresh=140 sysctl.net.core.netdev_unregister_timeout_secs=140 dummy_hcd.num=32 max_loop=32 nbds_max=32 comedi.comedi_num_legacy_minors=4"
# CONFIG_CMDLINE_OVERRIDE is not set
CONFIG_MODIFY_LDT_SYSCALL=y
# CONFIG_STRICT_SIGALTSTACK_SIZE is not set
CONFIG_HAVE_LIVEPATCH=y
CONFIG_HAVE_KLP_BUILD=y
CONFIG_X86_BUS_LOCK_DETECT=y
# end of Processor type and features

CONFIG_CC_HAS_NAMED_AS=y
CONFIG_CC_HAS_NAMED_AS_FIXED_SANITIZERS=y
CONFIG_USE_X86_SEG_SUPPORT=y
CONFIG_CC_HAS_SLS=y
CONFIG_CC_HAS_RETURN_THUNK=y
CONFIG_CC_HAS_ENTRY_PADDING=y
CONFIG_FUNCTION_PADDING_CFI=11
CONFIG_FUNCTION_PADDING_BYTES=16
CONFIG_CALL_PADDING=y
CONFIG_HAVE_CALL_THUNKS=y
CONFIG_CALL_THUNKS=y
CONFIG_CPU_MITIGATIONS=y
CONFIG_MITIGATION_PAGE_TABLE_ISOLATION=y
CONFIG_MITIGATION_RETPOLINE=y
CONFIG_MITIGATION_RETHUNK=y
CONFIG_MITIGATION_UNRET_ENTRY=y
CONFIG_MITIGATION_CALL_DEPTH_TRACKING=y
# CONFIG_CALL_THUNKS_DEBUG is not set
CONFIG_MITIGATION_IBPB_ENTRY=y
CONFIG_MITIGATION_IBRS_ENTRY=y
CONFIG_MITIGATION_SRSO=y
# CONFIG_MITIGATION_SLS is not set
CONFIG_MITIGATION_GDS=y
CONFIG_MITIGATION_RFDS=y
CONFIG_MITIGATION_SPECTRE_BHI=y
CONFIG_MITIGATION_MDS=y
CONFIG_MITIGATION_TAA=y
CONFIG_MITIGATION_MMIO_STALE_DATA=y
CONFIG_MITIGATION_L1TF=y
CONFIG_MITIGATION_RETBLEED=y
CONFIG_MITIGATION_SPECTRE_V1=y
CONFIG_MITIGATION_SPECTRE_V2=y
CONFIG_MITIGATION_SRBDS=y
CONFIG_MITIGATION_SSB=y
CONFIG_MITIGATION_ITS=y
CONFIG_MITIGATION_TSA=y
# CONFIG_MITIGATION_VMSCAPE is not set
CONFIG_ARCH_HAS_ADD_PAGES=y

#
# Power management and ACPI options
#
CONFIG_ARCH_HIBERNATION_HEADER=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
# CONFIG_SUSPEND_SKIP_SYNC is not set
CONFIG_HIBERNATE_CALLBACKS=y
CONFIG_HIBERNATION=y
CONFIG_HIBERNATION_SNAPSHOT_DEV=y
CONFIG_HIBERNATION_COMP_LZO=y
# CONFIG_HIBERNATION_COMP_LZ4 is not set
CONFIG_HIBERNATION_DEF_COMP="lzo"
CONFIG_PM_STD_PARTITION=""
CONFIG_PM_SLEEP=y
CONFIG_PM_SLEEP_SMP=y
# CONFIG_PM_AUTOSLEEP is not set
# CONFIG_PM_USERSPACE_AUTOSLEEP is not set
# CONFIG_PM_WAKELOCKS is not set
# CONFIG_PM_QOS_CPU_SYSTEM_WAKEUP is not set
CONFIG_PM=y
CONFIG_PM_DEBUG=y
# CONFIG_PM_ADVANCED_DEBUG is not set
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_PM_SLEEP_DEBUG=y
# CONFIG_DPM_WATCHDOG is not set
CONFIG_PM_TRACE=y
CONFIG_PM_TRACE_RTC=y
CONFIG_PM_CLK=y
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
# CONFIG_ENERGY_MODEL is not set
CONFIG_ARCH_SUPPORTS_ACPI=y
CONFIG_ACPI=y
CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y
CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y
CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
CONFIG_ACPI_THERMAL_LIB=y
# CONFIG_ACPI_DEBUGGER is not set
CONFIG_ACPI_SPCR_TABLE=y
# CONFIG_ACPI_FPDT is not set
CONFIG_ACPI_LPIT=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y
CONFIG_ACPI_EC=y
# CONFIG_ACPI_EC_DEBUGFS is not set
CONFIG_ACPI_AC=y
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_VIDEO=y
CONFIG_ACPI_FAN=y
# CONFIG_ACPI_TAD is not set
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_CPU_FREQ_PSS=y
CONFIG_ACPI_PROCESSOR_CSTATE=y
CONFIG_ACPI_PROCESSOR_IDLE=y
CONFIG_ACPI_CPPC_LIB=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_HOTPLUG_CPU=y
# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_PLATFORM_PROFILE=y
CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE=y
CONFIG_ACPI_TABLE_UPGRADE=y
CONFIG_ACPI_DEBUG=y
# CONFIG_ACPI_PCI_SLOT is not set
CONFIG_ACPI_CONTAINER=y
# CONFIG_ACPI_HOTPLUG_MEMORY is not set
CONFIG_ACPI_HOTPLUG_IOAPIC=y
# CONFIG_ACPI_SBS is not set
# CONFIG_ACPI_HED is not set
# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set
CONFIG_ACPI_NHLT=y
CONFIG_ACPI_NFIT=y
# CONFIG_NFIT_SECURITY_DEBUG is not set
CONFIG_ACPI_NUMA=y
# CONFIG_ACPI_HMAT is not set
CONFIG_HAVE_ACPI_APEI=y
CONFIG_HAVE_ACPI_APEI_NMI=y
# CONFIG_ACPI_APEI is not set
# CONFIG_ACPI_DPTF is not set
# CONFIG_ACPI_EXTLOG is not set
# CONFIG_ACPI_CONFIGFS is not set
# CONFIG_ACPI_PFRUT is not set
CONFIG_ACPI_PCC=y
# CONFIG_ACPI_FFH is not set
CONFIG_ACPI_MRRM=y
CONFIG_PMIC_OPREGION=y
CONFIG_BXT_WC_PMIC_OPREGION=y
# CONFIG_CHT_WC_PMIC_OPREGION is not set
CONFIG_X86_PM_TIMER=y

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
# CONFIG_CPU_FREQ_STAT is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y

#
# CPU frequency scaling drivers
#
# CONFIG_CPUFREQ_DT is not set
# CONFIG_CPUFREQ_DT_PLATDEV is not set
CONFIG_X86_INTEL_PSTATE=y
# CONFIG_X86_PCC_CPUFREQ is not set
CONFIG_X86_AMD_PSTATE=y
CONFIG_X86_AMD_PSTATE_DEFAULT_MODE=3
# CONFIG_X86_AMD_PSTATE_UT is not set
CONFIG_X86_ACPI_CPUFREQ=y
CONFIG_X86_ACPI_CPUFREQ_CPB=y
# CONFIG_X86_POWERNOW_K8 is not set
# CONFIG_X86_AMD_FREQ_SENSITIVITY is not set
# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
# CONFIG_X86_P4_CLOCKMOD is not set

#
# shared options
#
CONFIG_CPUFREQ_ARCH_CUR_FREQ=y
# end of CPU Frequency scaling

#
# CPU Idle
#
CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y
# CONFIG_CPU_IDLE_GOV_TEO is not set
CONFIG_CPU_IDLE_GOV_HALTPOLL=y
CONFIG_HALTPOLL_CPUIDLE=y
# end of CPU Idle

CONFIG_INTEL_IDLE=y
# end of Power management and ACPI options

#
# Bus options (PCI etc.)
#
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_MMCONF_FAM10H=y
CONFIG_ISA_BUS=y
CONFIG_ISA_DMA_API=y
CONFIG_AMD_NB=y
CONFIG_AMD_NODE=y
# end of Bus options (PCI etc.)

#
# Binary Emulations
#
CONFIG_IA32_EMULATION=y
# CONFIG_IA32_EMULATION_DEFAULT_DISABLED is not set
CONFIG_X86_X32_ABI=y
CONFIG_COMPAT_32=y
CONFIG_COMPAT=y
CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
# end of Binary Emulations

CONFIG_KVM_COMMON=y
CONFIG_HAVE_KVM_PFNCACHE=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_IRQ_ROUTING=y
CONFIG_HAVE_KVM_DIRTY_RING=y
CONFIG_HAVE_KVM_DIRTY_RING_TSO=y
CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL=y
CONFIG_KVM_MMIO=y
CONFIG_KVM_ASYNC_PF=y
CONFIG_HAVE_KVM_MSI=y
CONFIG_HAVE_KVM_READONLY_MEM=y
CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
CONFIG_KVM_VFIO=y
CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
CONFIG_KVM_GENERIC_PRE_FAULT_MEMORY=y
CONFIG_KVM_COMPAT=y
CONFIG_HAVE_KVM_IRQ_BYPASS=y
CONFIG_HAVE_KVM_NO_POLL=y
CONFIG_VIRT_XFER_TO_GUEST_WORK=y
CONFIG_HAVE_KVM_PM_NOTIFIER=y
CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y
CONFIG_KVM_ELIDE_TLB_FLUSH_IF_YOUNG=y
CONFIG_KVM_MMU_LOCKLESS_AGING=y
CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES=y
CONFIG_KVM_GUEST_MEMFD=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM_X86=y
CONFIG_KVM=y
# CONFIG_KVM_WERROR is not set
CONFIG_KVM_SW_PROTECTED_VM=y
CONFIG_KVM_INTEL=y
# CONFIG_KVM_INTEL_PROVE_VE is not set
CONFIG_X86_SGX_KVM=y
CONFIG_KVM_AMD=y
CONFIG_KVM_IOAPIC=y
CONFIG_KVM_SMM=y
CONFIG_KVM_HYPERV=y
CONFIG_KVM_XEN=y
CONFIG_KVM_PROVE_MMU=y
CONFIG_KVM_MAX_NR_VCPUS=1024
CONFIG_X86_REQUIRED_FEATURE_ALWAYS=y
CONFIG_X86_REQUIRED_FEATURE_NOPL=y
CONFIG_X86_REQUIRED_FEATURE_CX8=y
CONFIG_X86_REQUIRED_FEATURE_CMOV=y
CONFIG_X86_REQUIRED_FEATURE_CPUID=y
CONFIG_X86_REQUIRED_FEATURE_FPU=y
CONFIG_X86_REQUIRED_FEATURE_PAE=y
CONFIG_X86_REQUIRED_FEATURE_PSE=y
CONFIG_X86_REQUIRED_FEATURE_PGE=y
CONFIG_X86_REQUIRED_FEATURE_MSR=y
CONFIG_X86_REQUIRED_FEATURE_FXSR=y
CONFIG_X86_REQUIRED_FEATURE_XMM=y
CONFIG_X86_REQUIRED_FEATURE_XMM2=y
CONFIG_X86_REQUIRED_FEATURE_LM=y
CONFIG_X86_DISABLED_FEATURE_VME=y
CONFIG_X86_DISABLED_FEATURE_K6_MTRR=y
CONFIG_X86_DISABLED_FEATURE_CYRIX_ARR=y
CONFIG_X86_DISABLED_FEATURE_CENTAUR_MCR=y
CONFIG_X86_DISABLED_FEATURE_LAM=y
CONFIG_X86_DISABLED_FEATURE_XENPV=y
CONFIG_X86_DISABLED_FEATURE_TDX_GUEST=y
CONFIG_X86_DISABLED_FEATURE_SEV_SNP=y
CONFIG_AS_WRUSS=y
CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y

#
# General architecture-dependent options
#
CONFIG_HOTPLUG_SMT=y
CONFIG_ARCH_SUPPORTS_SCHED_SMT=y
CONFIG_ARCH_SUPPORTS_SCHED_CLUSTER=y
CONFIG_ARCH_SUPPORTS_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_SCHED_CLUSTER=y
CONFIG_SCHED_MC=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CORE_SYNC_FULL=y
CONFIG_HOTPLUG_SPLIT_STARTUP=y
CONFIG_HOTPLUG_PARALLEL=y
CONFIG_GENERIC_IRQ_ENTRY=y
CONFIG_GENERIC_SYSCALL=y
CONFIG_GENERIC_ENTRY=y
# CONFIG_KPROBES is not set
CONFIG_JUMP_LABEL=y
# CONFIG_STATIC_KEYS_SELFTEST is not set
# CONFIG_STATIC_CALL_SELFTEST is not set
CONFIG_UPROBES=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
CONFIG_HAVE_NMI=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
CONFIG_ARCH_HAS_SET_MEMORY=y
CONFIG_ARCH_HAS_SET_DIRECT_MAP=y
CONFIG_ARCH_HAS_CPU_FINALIZE_INIT=y
CONFIG_ARCH_HAS_CPU_PASID=y
CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_MEMORY_ORDER_TSO=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_RUST=y
CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y
CONFIG_UNWIND_USER=y
CONFIG_HAVE_UNWIND_USER_FP=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y
CONFIG_MMU_GATHER_TABLE_FREE=y
CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
CONFIG_MMU_GATHER_MERGE_VMAS=y
CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_ARCH_HAVE_EXTRA_ELF_NOTES=y
CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y
CONFIG_HAVE_ARCH_SECCOMP=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y
# CONFIG_SECCOMP_CACHE_DEBUG is not set
CONFIG_HAVE_ARCH_KSTACK_ERASE=y
CONFIG_HAVE_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR_STRONG=y
CONFIG_ARCH_SUPPORTS_LTO_CLANG=y
CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y
CONFIG_LTO_NONE=y
CONFIG_ARCH_SUPPORTS_CFI=y
CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
CONFIG_HAVE_CONTEXT_TRACKING_USER=y
CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_PV_STEAL_CLOCK_GEN=y
CONFIG_HAVE_MOVE_PUD=y
CONFIG_HAVE_MOVE_PMD=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y
CONFIG_HAVE_ARCH_HUGE_VMAP=y
CONFIG_HAVE_ARCH_HUGE_VMALLOC=y
CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
CONFIG_ARCH_WANT_PMD_MKWRITE=y
CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_ARCH_HAS_EXECMEM_ROX=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
CONFIG_HAVE_EXIT_THREAD=y
CONFIG_ARCH_MMAP_RND_BITS=28
CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y
CONFIG_ARCH_MMAP_RND_COMPAT_BITS=8
CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES=y
CONFIG_HAVE_PAGE_SIZE_4KB=y
CONFIG_PAGE_SIZE_4KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SHIFT=12
CONFIG_HAVE_OBJTOOL=y
CONFIG_HAVE_JUMP_LABEL_HACK=y
CONFIG_HAVE_NOINSTR_HACK=y
CONFIG_HAVE_NOINSTR_VALIDATION=y
CONFIG_HAVE_UACCESS_VALIDATION=y
CONFIG_HAVE_STACK_VALIDATION=y
CONFIG_HAVE_RELIABLE_STACKTRACE=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_COMPAT_OLD_SIGACTION=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_ARCH_SUPPORTS_RT=y
CONFIG_HAVE_ARCH_VMAP_STACK=y
CONFIG_VMAP_STACK=y
CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y
CONFIG_RANDOMIZE_KSTACK_OFFSET=y
# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
CONFIG_STRICT_MODULE_RWX=y
CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
# CONFIG_LOCK_EVENT_COUNTS is not set
CONFIG_ARCH_HAS_MEM_ENCRYPT=y
CONFIG_HAVE_STATIC_CALL=y
CONFIG_HAVE_STATIC_CALL_INLINE=y
CONFIG_HAVE_PREEMPT_DYNAMIC=y
CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y
CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y
CONFIG_ARCH_HAS_ELFCORE_COMPAT=y
CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y
CONFIG_DYNAMIC_SIGFRAME=y
CONFIG_HAVE_ARCH_NODE_DEV_GROUP=y
CONFIG_ARCH_HAS_HW_PTE_YOUNG=y
CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y
CONFIG_ARCH_HAS_KERNEL_FPU_SUPPORT=y
CONFIG_HAVE_GENERIC_TIF_BITS=y

#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling

CONFIG_HAVE_GCC_PLUGINS=y
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FUNCTION_ALIGNMENT_16B=y
CONFIG_FUNCTION_ALIGNMENT=16
CONFIG_CC_HAS_MIN_FUNCTION_ALIGNMENT=y
CONFIG_CC_HAS_SANE_FUNCTION_ALIGNMENT=y
CONFIG_ARCH_HAS_CPU_ATTACK_VECTORS=y
# end of General architecture-dependent options

CONFIG_RT_MUTEXES=y
CONFIG_MODULE_SIG_FORMAT=y
CONFIG_MODULES=y
# CONFIG_MODULE_DEBUG is not set
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set
CONFIG_MODVERSIONS=y
# CONFIG_GENKSYMS is not set
CONFIG_GENDWARFKSYMS=y
CONFIG_ASM_MODVERSIONS=y
# CONFIG_EXTENDED_MODVERSIONS is not set
# CONFIG_BASIC_MODVERSIONS is not set
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_MODULE_SIG=y
# CONFIG_MODULE_SIG_FORCE is not set
# CONFIG_MODULE_SIG_ALL is not set
CONFIG_MODULE_SIG_SHA256=y
# CONFIG_MODULE_SIG_SHA384 is not set
# CONFIG_MODULE_SIG_SHA512 is not set
# CONFIG_MODULE_SIG_SHA3_256 is not set
# CONFIG_MODULE_SIG_SHA3_384 is not set
# CONFIG_MODULE_SIG_SHA3_512 is not set
CONFIG_MODULE_SIG_HASH="sha256"
# CONFIG_MODULE_COMPRESS is not set
# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
CONFIG_MODPROBE_PATH="/sbin/modprobe"
# CONFIG_TRIM_UNUSED_KSYMS is not set
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_BLOCK=y
CONFIG_BLOCK_LEGACY_AUTOLOAD=y
CONFIG_BLK_RQ_ALLOC_TIME=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_CGROUP_PUNT_BIO=y
CONFIG_BLK_DEV_BSG_COMMON=y
CONFIG_BLK_ICQ=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_INTEGRITY=y
# CONFIG_BLK_DEV_WRITE_MOUNTED is not set
CONFIG_BLK_DEV_ZONED=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_BLK_WBT=y
CONFIG_BLK_WBT_MQ=y
CONFIG_BLK_CGROUP_IOLATENCY=y
# CONFIG_BLK_CGROUP_FC_APPID is not set
CONFIG_BLK_CGROUP_IOCOST=y
CONFIG_BLK_CGROUP_IOPRIO=y
CONFIG_BLK_DEBUG_FS=y
# CONFIG_BLK_SED_OPAL is not set
CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_CUMANA=y
CONFIG_ACORN_PARTITION_EESOX=y
CONFIG_ACORN_PARTITION_ICS=y
CONFIG_ACORN_PARTITION_ADFS=y
CONFIG_ACORN_PARTITION_POWERTEC=y
CONFIG_ACORN_PARTITION_RISCIX=y
CONFIG_AIX_PARTITION=y
CONFIG_OSF_PARTITION=y
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
CONFIG_MINIX_SUBPARTITION=y
CONFIG_SOLARIS_X86_PARTITION=y
CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_LDM_PARTITION=y
# CONFIG_LDM_DEBUG is not set
CONFIG_SGI_PARTITION=y
CONFIG_ULTRIX_PARTITION=y
CONFIG_SUN_PARTITION=y
CONFIG_KARMA_PARTITION=y
CONFIG_EFI_PARTITION=y
CONFIG_SYSV68_PARTITION=y
CONFIG_CMDLINE_PARTITION=y
# CONFIG_OF_PARTITION is not set
# end of Partition Types

CONFIG_BLK_PM=y
CONFIG_BLOCK_HOLDER_DEPRECATED=y
CONFIG_BLK_MQ_STACKING=y
# CONFIG_BLK_ERROR_INJECTION is not set

#
# IO Schedulers
#
CONFIG_MQ_IOSCHED_DEADLINE=y
CONFIG_MQ_IOSCHED_KYBER=y
CONFIG_IOSCHED_BFQ=y
CONFIG_BFQ_GROUP_IOSCHED=y
CONFIG_BFQ_CGROUP_DEBUG=y
# end of IO Schedulers

CONFIG_PREEMPT_NOTIFIERS=y
CONFIG_PADATA=y
CONFIG_ASN1=y
CONFIG_UNINLINE_SPIN_UNLOCK=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y
CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y
CONFIG_FREEZER=y

#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_ELFCORE=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_BINFMT_MISC=y
CONFIG_COREDUMP=y
# end of Executable file formats

#
# Memory Management options
#
CONFIG_SWAP=y
CONFIG_ZSWAP=y
CONFIG_ZSWAP_DEFAULT_ON=y
CONFIG_ZSWAP_SHRINKER_DEFAULT_ON=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT="842"
CONFIG_ZSMALLOC=y

#
# Zsmalloc allocator options
#

#
# Zsmalloc is a common backend allocator for zswap & zram
#
# CONFIG_ZSMALLOC_STAT is not set
CONFIG_ZSMALLOC_CHAIN_SIZE=8
# end of Zsmalloc allocator options

#
# Slab allocator options
#
CONFIG_SLUB=y
CONFIG_KVFREE_RCU_BATCHED=y
# CONFIG_SLUB_TINY is not set
CONFIG_SLAB_MERGE_DEFAULT=y
# CONFIG_SLAB_FREELIST_RANDOM is not set
# CONFIG_SLAB_FREELIST_HARDENED is not set
# CONFIG_SLAB_BUCKETS is not set
# CONFIG_SLUB_STATS is not set
# CONFIG_KMALLOC_PARTITION_CACHES is not set
# end of Slab allocator options

# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPARSEMEM_VMEMMAP_PREINIT=y
CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP=y
CONFIG_ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP=y
CONFIG_ARCH_WANT_HUGETLB_VMEMMAP_PREINIT=y
CONFIG_HAVE_GUP_FAST=y
CONFIG_NUMA_KEEP_MEMINFO=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_HAVE_BOOTMEM_INFO_NODE=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTPLUG=y
# CONFIG_MHP_DEFAULT_ONLINE_TYPE_OFFLINE is not set
CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_AUTO=y
# CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_KERNEL is not set
# CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_MOVABLE is not set
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_MHP_MEMMAP_ON_MEMORY=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
CONFIG_SPLIT_PTE_PTLOCKS=y
CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
CONFIG_SPLIT_PMD_PTLOCKS=y
CONFIG_BALLOON=y
# CONFIG_BALLOON_MIGRATION is not set
CONFIG_COMPACTION=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_PAGE_REPORTING=y
CONFIG_NUMA_MIGRATION=y
CONFIG_MIGRATION=y
CONFIG_DEVICE_MIGRATION=y
CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y
CONFIG_ARCH_ENABLE_THP_MIGRATION=y
CONFIG_CONTIG_ALLOC=y
CONFIG_PCP_BATCH_SCALE_MAX=5
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_MMU_NOTIFIER=y
CONFIG_KSM=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y
# CONFIG_MEMORY_FAILURE is not set
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ARCH_WANTS_THP_SWAP=y
# CONFIG_PERSISTENT_HUGE_ZERO_FOLIO is not set
CONFIG_MM_ID=y
CONFIG_TRANSPARENT_HUGEPAGE=y
# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
# CONFIG_TRANSPARENT_HUGEPAGE_NEVER is not set
# CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_NEVER is not set
# CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ALWAYS is not set
# CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_WITHIN_SIZE is not set
CONFIG_TRANSPARENT_HUGEPAGE_SHMEM_HUGE_ADVISE=y
# CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_NEVER is not set
# CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ALWAYS is not set
# CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_WITHIN_SIZE is not set
CONFIG_TRANSPARENT_HUGEPAGE_TMPFS_HUGE_ADVISE=y
CONFIG_THP_SWAP=y
# CONFIG_NO_PAGE_MAPCOUNT is not set
CONFIG_PAGE_MAPCOUNT=y
CONFIG_PGTABLE_HAS_HUGE_LEAVES=y
CONFIG_HAVE_GIGANTIC_FOLIOS=y
CONFIG_ASYNC_KERNEL_PGTABLE_FREE=y
CONFIG_ARCH_SUPPORTS_HUGE_PFNMAP=y
CONFIG_ARCH_SUPPORTS_PMD_PFNMAP=y
CONFIG_ARCH_SUPPORTS_PUD_PFNMAP=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_USE_PERCPU_NUMA_NODE_ID=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_CMA=y
# CONFIG_CMA_DEBUGFS is not set
# CONFIG_CMA_SYSFS is not set
CONFIG_CMA_AREAS=20
CONFIG_PAGE_BLOCK_MAX_ORDER=10
CONFIG_MEM_SOFT_DIRTY=y
CONFIG_GENERIC_EARLY_IOREMAP=y
# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set
CONFIG_PAGE_IDLE_FLAG=y
# CONFIG_IDLE_PAGE_TRACKING is not set
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y
CONFIG_ARCH_HAS_ZONE_DMA_SET=y
CONFIG_ZONE_DMA=y
CONFIG_ZONE_DMA32=y
CONFIG_ZONE_DEVICE=y
CONFIG_HMM_MIRROR=y
CONFIG_GET_FREE_REGION=y
CONFIG_DEVICE_PRIVATE=y
CONFIG_VMAP_PFN=y
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
CONFIG_ARCH_HAS_PKEYS=y
CONFIG_ARCH_USES_PG_ARCH_2=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PERCPU_STATS=y
# CONFIG_GUP_TEST is not set
# CONFIG_DMAPOOL_TEST is not set
CONFIG_ARCH_HAS_PTE_SPECIAL=y
CONFIG_MAPPING_DIRTY_HELPERS=y
CONFIG_MEMFD_CREATE=y
CONFIG_SECRETMEM=y
CONFIG_ANON_VMA_NAME=y
CONFIG_HAVE_ARCH_USERFAULTFD_WP=y
CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y
CONFIG_USERFAULTFD=y
# CONFIG_PTE_MARKER_UFFD_WP is not set
CONFIG_LRU_GEN=y
CONFIG_LRU_GEN_ENABLED=y
# CONFIG_LRU_GEN_STATS is not set
CONFIG_LRU_GEN_WALKS_MMU=y
CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK=y
CONFIG_PER_VMA_LOCK=y
CONFIG_LOCK_MM_AND_FIND_VMA=y
CONFIG_IOMMU_MM_DATA=y
CONFIG_EXECMEM=y
CONFIG_NUMA_MEMBLKS=y
CONFIG_NUMA_EMU=y
CONFIG_ARCH_HAS_USER_SHADOW_STACK=y
CONFIG_PT_RECLAIM=y

#
# Data Access Monitoring
#
CONFIG_DAMON=y
# CONFIG_DAMON_DEBUG_SANITY is not set
CONFIG_DAMON_VADDR=y
CONFIG_DAMON_PADDR=y
# CONFIG_DAMON_SYSFS is not set
CONFIG_DAMON_RECLAIM=y
# CONFIG_DAMON_LRU_SORT is not set
# CONFIG_DAMON_STAT is not set
# end of Data Access Monitoring
# end of Memory Management options

CONFIG_NET=y
CONFIG_WANT_COMPAT_NETLINK_MESSAGES=y
CONFIG_COMPAT_NETLINK_MESSAGES=y
CONFIG_NET_INGRESS=y
CONFIG_NET_EGRESS=y
CONFIG_NET_XGRESS=y
CONFIG_NET_REDIRECT=y
CONFIG_SKB_DECRYPTED=y
CONFIG_SKB_EXTENSIONS=y
CONFIG_NET_DEVMEM=y
CONFIG_NET_SHAPER=y
CONFIG_NET_CRC32C=y

#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
CONFIG_INET_PSP=y
CONFIG_UNIX=y
CONFIG_AF_UNIX_OOB=y
CONFIG_UNIX_DIAG=y
CONFIG_TLS=y
CONFIG_TLS_DEVICE=y
CONFIG_XFRM=y
CONFIG_XFRM_OFFLOAD=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
CONFIG_XFRM_USER_COMPAT=y
CONFIG_XFRM_INTERFACE=y
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_XFRM_STATISTICS=y
CONFIG_XFRM_AH=y
CONFIG_XFRM_ESP=y
CONFIG_XFRM_IPCOMP=y
CONFIG_NET_KEY=y
CONFIG_NET_KEY_MIGRATE=y
# CONFIG_XFRM_IPTFS is not set
CONFIG_XFRM_ESPINTCP=y
CONFIG_SMC=y
CONFIG_SMC_DIAG=y
# CONFIG_SMC_HS_CTRL_BPF is not set
CONFIG_DIBS=y
CONFIG_DIBS_LO=y
CONFIG_XDP_SOCKETS=y
CONFIG_XDP_SOCKETS_DIAG=y
CONFIG_NET_HANDSHAKE=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_FIB_TRIE_STATS=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_ROUTE_CLASSID=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_NET_IPIP=y
CONFIG_NET_IPGRE_DEMUX=y
CONFIG_NET_IP_TUNNEL=y
CONFIG_NET_IPGRE=y
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE_COMMON=y
CONFIG_IP_MROUTE=y
CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_SYN_COOKIES=y
CONFIG_NET_IPVTI=y
CONFIG_NET_UDP_TUNNEL=y
CONFIG_NET_FOU=y
CONFIG_NET_FOU_IP_TUNNELS=y
CONFIG_INET_AH=y
CONFIG_INET_ESP=y
CONFIG_INET_ESP_OFFLOAD=y
CONFIG_INET_ESPINTCP=y
CONFIG_INET_IPCOMP=y
CONFIG_INET_TABLE_PERTURB_ORDER=16
CONFIG_INET_XFRM_TUNNEL=y
CONFIG_INET_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
CONFIG_INET_UDP_DIAG=y
CONFIG_INET_RAW_DIAG=y
CONFIG_INET_DIAG_DESTROY=y
CONFIG_TCP_CONG_ADVANCED=y
CONFIG_TCP_CONG_BIC=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_TCP_CONG_WESTWOOD=y
CONFIG_TCP_CONG_HTCP=y
CONFIG_TCP_CONG_HSTCP=y
CONFIG_TCP_CONG_HYBLA=y
CONFIG_TCP_CONG_VEGAS=y
CONFIG_TCP_CONG_NV=y
CONFIG_TCP_CONG_SCALABLE=y
CONFIG_TCP_CONG_LP=y
CONFIG_TCP_CONG_VENO=y
CONFIG_TCP_CONG_YEAH=y
CONFIG_TCP_CONG_ILLINOIS=y
CONFIG_TCP_CONG_DCTCP=y
CONFIG_TCP_CONG_CDG=y
CONFIG_TCP_CONG_BBR=y
# CONFIG_DEFAULT_BIC is not set
CONFIG_DEFAULT_CUBIC=y
# CONFIG_DEFAULT_HTCP is not set
# CONFIG_DEFAULT_HYBLA is not set
# CONFIG_DEFAULT_VEGAS is not set
# CONFIG_DEFAULT_VENO is not set
# CONFIG_DEFAULT_WESTWOOD is not set
# CONFIG_DEFAULT_DCTCP is not set
# CONFIG_DEFAULT_CDG is not set
# CONFIG_DEFAULT_BBR is not set
# CONFIG_DEFAULT_RENO is not set
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_AO is not set
CONFIG_TCP_MD5SIG=y
CONFIG_IPV6=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=y
CONFIG_INET6_ESP=y
CONFIG_INET6_ESP_OFFLOAD=y
CONFIG_INET6_ESPINTCP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
CONFIG_IPV6_ILA=y
CONFIG_INET6_XFRM_TUNNEL=y
CONFIG_INET6_TUNNEL=y
CONFIG_IPV6_VTI=y
CONFIG_IPV6_SIT=y
CONFIG_IPV6_SIT_6RD=y
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=y
CONFIG_IPV6_GRE=y
CONFIG_IPV6_FOU=y
CONFIG_IPV6_FOU_TUNNEL=y
CONFIG_IPV6_MULTIPLE_TABLES=y
CONFIG_IPV6_SUBTREES=y
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
CONFIG_IPV6_PIMSM_V2=y
CONFIG_IPV6_SEG6_LWTUNNEL=y
CONFIG_IPV6_SEG6_HMAC=y
CONFIG_IPV6_SEG6_BPF=y
CONFIG_IPV6_RPL_LWTUNNEL=y
# CONFIG_IPV6_IOAM6_LWTUNNEL is not set
CONFIG_NETLABEL=y
CONFIG_MPTCP=y
CONFIG_INET_MPTCP_DIAG=y
CONFIG_MPTCP_IPV6=y
CONFIG_NETWORK_SECMARK=y
CONFIG_NET_PTP_CLASSIFY=y
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_BRIDGE_NETFILTER=y

#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_INGRESS=y
CONFIG_NETFILTER_EGRESS=y
CONFIG_NETFILTER_SKIP_EGRESS=y
CONFIG_NETFILTER_NETLINK=y
CONFIG_NETFILTER_FAMILY_BRIDGE=y
CONFIG_NETFILTER_FAMILY_ARP=y
CONFIG_NETFILTER_BPF_LINK=y
# CONFIG_NETFILTER_NETLINK_HOOK is not set
CONFIG_NETFILTER_NETLINK_ACCT=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NETFILTER_NETLINK_LOG=y
CONFIG_NETFILTER_NETLINK_OSF=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_LOG_SYSLOG=y
CONFIG_NETFILTER_CONNCOUNT=y
CONFIG_NF_CONNTRACK_MARK=y
CONFIG_NF_CONNTRACK_SECMARK=y
CONFIG_NF_CONNTRACK_ZONES=y
# CONFIG_NF_CONNTRACK_PROCFS is not set
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CONNTRACK_TIMEOUT=y
CONFIG_NF_CONNTRACK_TIMESTAMP=y
CONFIG_NF_CONNTRACK_LABELS=y
CONFIG_NF_CONNTRACK_OVS=y
CONFIG_NF_CT_PROTO_GRE=y
CONFIG_NF_CT_PROTO_SCTP=y
CONFIG_NF_CONNTRACK_AMANDA=y
CONFIG_NF_CONNTRACK_FTP=y
CONFIG_NF_CONNTRACK_H323=y
CONFIG_NF_CONNTRACK_IRC=y
CONFIG_NF_CONNTRACK_BROADCAST=y
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
CONFIG_NF_CONNTRACK_SNMP=y
CONFIG_NF_CONNTRACK_PPTP=y
CONFIG_NF_CONNTRACK_SANE=y
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
CONFIG_NF_CT_NETLINK_TIMEOUT=y
CONFIG_NF_CT_NETLINK_HELPER=y
CONFIG_NETFILTER_NETLINK_GLUE_CT=y
CONFIG_NF_NAT=y
CONFIG_NF_NAT_AMANDA=y
CONFIG_NF_NAT_FTP=y
CONFIG_NF_NAT_IRC=y
CONFIG_NF_NAT_SIP=y
CONFIG_NF_NAT_TFTP=y
CONFIG_NF_NAT_REDIRECT=y
CONFIG_NF_NAT_MASQUERADE=y
CONFIG_NF_NAT_OVS=y
CONFIG_NETFILTER_SYNPROXY=y
CONFIG_NF_TABLES=y
CONFIG_NF_TABLES_INET=y
CONFIG_NF_TABLES_NETDEV=y
CONFIG_NFT_NUMGEN=y
CONFIG_NFT_CT=y
CONFIG_NFT_EXTHDR_DCCP=y
CONFIG_NFT_FLOW_OFFLOAD=y
CONFIG_NFT_CONNLIMIT=y
CONFIG_NFT_LOG=y
CONFIG_NFT_LIMIT=y
CONFIG_NFT_MASQ=y
CONFIG_NFT_REDIR=y
CONFIG_NFT_NAT=y
CONFIG_NFT_TUNNEL=y
CONFIG_NFT_QUEUE=y
CONFIG_NFT_QUOTA=y
CONFIG_NFT_REJECT=y
CONFIG_NFT_REJECT_INET=y
CONFIG_NFT_COMPAT=y
CONFIG_NFT_HASH=y
CONFIG_NFT_FIB=y
CONFIG_NFT_FIB_INET=y
CONFIG_NFT_XFRM=y
CONFIG_NFT_SOCKET=y
CONFIG_NFT_OSF=y
CONFIG_NFT_TPROXY=y
CONFIG_NFT_SYNPROXY=y
CONFIG_NF_DUP_NETDEV=y
CONFIG_NFT_DUP_NETDEV=y
CONFIG_NFT_FWD_NETDEV=y
CONFIG_NFT_FIB_NETDEV=y
CONFIG_NFT_REJECT_NETDEV=y
CONFIG_NF_FLOW_TABLE_INET=y
CONFIG_NF_FLOW_TABLE=y
# CONFIG_NF_FLOW_TABLE_PROCFS is not set
CONFIG_NETFILTER_XTABLES=y
CONFIG_NETFILTER_XTABLES_COMPAT=y
CONFIG_NETFILTER_XTABLES_LEGACY=y

#
# Xtables combined modules
#
CONFIG_NETFILTER_XT_MARK=y
CONFIG_NETFILTER_XT_CONNMARK=y
CONFIG_NETFILTER_XT_SET=y

#
# Xtables targets
#
CONFIG_NETFILTER_XT_TARGET_AUDIT=y
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
CONFIG_NETFILTER_XT_TARGET_CT=y
CONFIG_NETFILTER_XT_TARGET_DSCP=y
CONFIG_NETFILTER_XT_TARGET_HL=y
CONFIG_NETFILTER_XT_TARGET_HMARK=y
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
CONFIG_NETFILTER_XT_TARGET_LED=y
CONFIG_NETFILTER_XT_TARGET_LOG=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
CONFIG_NETFILTER_XT_NAT=y
CONFIG_NETFILTER_XT_TARGET_NETMAP=y
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
CONFIG_NETFILTER_XT_TARGET_RATEEST=y
CONFIG_NETFILTER_XT_TARGET_REDIRECT=y
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=y
CONFIG_NETFILTER_XT_TARGET_TEE=y
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
CONFIG_NETFILTER_XT_TARGET_TRACE=y
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=y

#
# Xtables matches
#
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
CONFIG_NETFILTER_XT_MATCH_CGROUP=y
CONFIG_NETFILTER_XT_MATCH_CLUSTER=y
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
CONFIG_NETFILTER_XT_MATCH_CPU=y
CONFIG_NETFILTER_XT_MATCH_DCCP=y
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=y
CONFIG_NETFILTER_XT_MATCH_DSCP=y
CONFIG_NETFILTER_XT_MATCH_ECN=y
CONFIG_NETFILTER_XT_MATCH_ESP=y
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HELPER=y
CONFIG_NETFILTER_XT_MATCH_HL=y
CONFIG_NETFILTER_XT_MATCH_IPCOMP=y
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
CONFIG_NETFILTER_XT_MATCH_IPVS=y
CONFIG_NETFILTER_XT_MATCH_L2TP=y
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
CONFIG_NETFILTER_XT_MATCH_MAC=y
CONFIG_NETFILTER_XT_MATCH_MARK=y
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
CONFIG_NETFILTER_XT_MATCH_NFACCT=y
CONFIG_NETFILTER_XT_MATCH_OSF=y
CONFIG_NETFILTER_XT_MATCH_OWNER=y
CONFIG_NETFILTER_XT_MATCH_POLICY=y
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=y
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
CONFIG_NETFILTER_XT_MATCH_RATEEST=y
CONFIG_NETFILTER_XT_MATCH_REALM=y
CONFIG_NETFILTER_XT_MATCH_RECENT=y
CONFIG_NETFILTER_XT_MATCH_SCTP=y
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
CONFIG_NETFILTER_XT_MATCH_TCPMSS=y
CONFIG_NETFILTER_XT_MATCH_TIME=y
CONFIG_NETFILTER_XT_MATCH_U32=y
# end of Core Netfilter Configuration

CONFIG_IP_SET=y
CONFIG_IP_SET_MAX=256
CONFIG_IP_SET_BITMAP_IP=y
CONFIG_IP_SET_BITMAP_IPMAC=y
CONFIG_IP_SET_BITMAP_PORT=y
CONFIG_IP_SET_HASH_IP=y
CONFIG_IP_SET_HASH_IPMARK=y
CONFIG_IP_SET_HASH_IPPORT=y
CONFIG_IP_SET_HASH_IPPORTIP=y
CONFIG_IP_SET_HASH_IPPORTNET=y
CONFIG_IP_SET_HASH_IPMAC=y
CONFIG_IP_SET_HASH_MAC=y
CONFIG_IP_SET_HASH_NETPORTNET=y
CONFIG_IP_SET_HASH_NET=y
CONFIG_IP_SET_HASH_NETNET=y
CONFIG_IP_SET_HASH_NETPORT=y
CONFIG_IP_SET_HASH_NETIFACE=y
CONFIG_IP_SET_LIST_SET=y
CONFIG_IP_VS=y
CONFIG_IP_VS_IPV6=y
# CONFIG_IP_VS_DEBUG is not set
CONFIG_IP_VS_TAB_BITS=12

#
# IPVS transport protocol load balancing support
#
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y

#
# IPVS scheduler
#
CONFIG_IP_VS_RR=y
CONFIG_IP_VS_WRR=y
CONFIG_IP_VS_LC=y
CONFIG_IP_VS_WLC=y
CONFIG_IP_VS_FO=y
CONFIG_IP_VS_OVF=y
CONFIG_IP_VS_LBLC=y
CONFIG_IP_VS_LBLCR=y
CONFIG_IP_VS_DH=y
CONFIG_IP_VS_SH=y
CONFIG_IP_VS_MH=y
CONFIG_IP_VS_SED=y
CONFIG_IP_VS_NQ=y
CONFIG_IP_VS_TWOS=y

#
# IPVS SH scheduler
#
CONFIG_IP_VS_SH_TAB_BITS=8

#
# IPVS MH scheduler
#
CONFIG_IP_VS_MH_TAB_INDEX=12

#
# IPVS application helper
#
CONFIG_IP_VS_FTP=y
CONFIG_IP_VS_NFCT=y
CONFIG_IP_VS_PE_SIP=y

#
# IP: Netfilter Configuration
#
CONFIG_NF_DEFRAG_IPV4=y
CONFIG_IP_NF_IPTABLES_LEGACY=y
CONFIG_NF_SOCKET_IPV4=y
CONFIG_NF_TPROXY_IPV4=y
CONFIG_NF_TABLES_IPV4=y
CONFIG_NFT_REJECT_IPV4=y
CONFIG_NFT_DUP_IPV4=y
CONFIG_NFT_FIB_IPV4=y
CONFIG_NF_TABLES_ARP=y
CONFIG_NF_DUP_IPV4=y
CONFIG_NF_LOG_ARP=y
CONFIG_NF_LOG_IPV4=y
CONFIG_NF_REJECT_IPV4=y
CONFIG_NF_NAT_SNMP_BASIC=y
CONFIG_NF_NAT_PPTP=y
CONFIG_NF_NAT_H323=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_RPFILTER=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_TARGET_SYNPROXY=y
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_TARGET_ECN=y
CONFIG_IP_NF_TARGET_TTL=y
CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_SECURITY=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_NFT_COMPAT_ARP=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
# end of IP: Netfilter Configuration

#
# IPv6: Netfilter Configuration
#
CONFIG_IP6_NF_IPTABLES_LEGACY=y
CONFIG_NF_SOCKET_IPV6=y
CONFIG_NF_TPROXY_IPV6=y
CONFIG_NF_TABLES_IPV6=y
CONFIG_NFT_REJECT_IPV6=y
CONFIG_NFT_DUP_IPV6=y
CONFIG_NFT_FIB_IPV6=y
CONFIG_NF_DUP_IPV6=y
CONFIG_NF_REJECT_IPV6=y
CONFIG_NF_LOG_IPV6=y
CONFIG_IP6_NF_IPTABLES=y
CONFIG_IP6_NF_MATCH_AH=y
CONFIG_IP6_NF_MATCH_EUI64=y
CONFIG_IP6_NF_MATCH_FRAG=y
CONFIG_IP6_NF_MATCH_OPTS=y
CONFIG_IP6_NF_MATCH_HL=y
CONFIG_IP6_NF_MATCH_IPV6HEADER=y
CONFIG_IP6_NF_MATCH_MH=y
CONFIG_IP6_NF_MATCH_RPFILTER=y
CONFIG_IP6_NF_MATCH_RT=y
CONFIG_IP6_NF_MATCH_SRH=y
CONFIG_IP6_NF_TARGET_HL=y
CONFIG_IP6_NF_FILTER=y
CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_TARGET_SYNPROXY=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_RAW=y
CONFIG_IP6_NF_SECURITY=y
CONFIG_IP6_NF_NAT=y
CONFIG_IP6_NF_TARGET_MASQUERADE=y
CONFIG_IP6_NF_TARGET_NPT=y
# end of IPv6: Netfilter Configuration

CONFIG_NF_DEFRAG_IPV6=y
CONFIG_NF_TABLES_BRIDGE=y
CONFIG_NFT_BRIDGE_META=y
CONFIG_NFT_BRIDGE_REJECT=y
CONFIG_NF_CONNTRACK_BRIDGE=y
CONFIG_BRIDGE_NF_EBTABLES_LEGACY=y
CONFIG_BRIDGE_NF_EBTABLES=y
CONFIG_BRIDGE_EBT_BROUTE=y
CONFIG_BRIDGE_EBT_T_FILTER=y
CONFIG_BRIDGE_EBT_T_NAT=y
CONFIG_BRIDGE_EBT_802_3=y
CONFIG_BRIDGE_EBT_AMONG=y
CONFIG_BRIDGE_EBT_ARP=y
CONFIG_BRIDGE_EBT_IP=y
CONFIG_BRIDGE_EBT_IP6=y
CONFIG_BRIDGE_EBT_LIMIT=y
CONFIG_BRIDGE_EBT_MARK=y
CONFIG_BRIDGE_EBT_PKTTYPE=y
CONFIG_BRIDGE_EBT_STP=y
CONFIG_BRIDGE_EBT_VLAN=y
CONFIG_BRIDGE_EBT_ARPREPLY=y
CONFIG_BRIDGE_EBT_DNAT=y
CONFIG_BRIDGE_EBT_MARK_T=y
CONFIG_BRIDGE_EBT_REDIRECT=y
CONFIG_BRIDGE_EBT_SNAT=y
CONFIG_BRIDGE_EBT_LOG=y
CONFIG_BRIDGE_EBT_NFLOG=y
CONFIG_IP_SCTP=y
# CONFIG_SCTP_DBG_OBJCNT is not set
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA256=y
# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set
CONFIG_INET_SCTP_DIAG=y
CONFIG_RDS=y
CONFIG_RDS_RDMA=y
CONFIG_RDS_TCP=y
# CONFIG_RDS_DEBUG is not set
CONFIG_TIPC=y
CONFIG_TIPC_MEDIA_IB=y
CONFIG_TIPC_MEDIA_UDP=y
CONFIG_TIPC_CRYPTO=y
CONFIG_TIPC_DIAG=y
CONFIG_ATM=y
CONFIG_ATM_BR2684=y
# CONFIG_ATM_BR2684_IPFILTER is not set
CONFIG_L2TP=y
# CONFIG_L2TP_DEBUGFS is not set
CONFIG_L2TP_V3=y
CONFIG_L2TP_IP=y
CONFIG_L2TP_ETH=y
CONFIG_STP=y
CONFIG_GARP=y
CONFIG_MRP=y
CONFIG_BRIDGE=y
CONFIG_BRIDGE_IGMP_SNOOPING=y
CONFIG_BRIDGE_VLAN_FILTERING=y
CONFIG_BRIDGE_MRP=y
CONFIG_BRIDGE_CFM=y
CONFIG_NET_DSA=y
# CONFIG_NET_DSA_TAG_NONE is not set
# CONFIG_NET_DSA_TAG_AR9331 is not set
CONFIG_NET_DSA_TAG_BRCM_COMMON=y
CONFIG_NET_DSA_TAG_BRCM=y
# CONFIG_NET_DSA_TAG_BRCM_LEGACY is not set
# CONFIG_NET_DSA_TAG_BRCM_LEGACY_FCS is not set
CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
# CONFIG_NET_DSA_TAG_HELLCREEK is not set
# CONFIG_NET_DSA_TAG_GSWIP is not set
# CONFIG_NET_DSA_TAG_DSA is not set
# CONFIG_NET_DSA_TAG_EDSA is not set
CONFIG_NET_DSA_TAG_MTK=y
# CONFIG_NET_DSA_TAG_MXL_862XX is not set
# CONFIG_NET_DSA_TAG_MXL_GSW1XX is not set
# CONFIG_NET_DSA_TAG_KSZ is not set
# CONFIG_NET_DSA_TAG_NETC is not set
# CONFIG_NET_DSA_TAG_OCELOT is not set
# CONFIG_NET_DSA_TAG_OCELOT_8021Q is not set
CONFIG_NET_DSA_TAG_QCA=y
CONFIG_NET_DSA_TAG_RTL4_A=y
# CONFIG_NET_DSA_TAG_RTL8_4 is not set
# CONFIG_NET_DSA_TAG_RZN1_A5PSW is not set
# CONFIG_NET_DSA_TAG_LAN9303 is not set
# CONFIG_NET_DSA_TAG_SJA1105 is not set
# CONFIG_NET_DSA_TAG_TRAILER is not set
# CONFIG_NET_DSA_TAG_VSC73XX_8021Q is not set
# CONFIG_NET_DSA_TAG_XRS700X is not set
# CONFIG_NET_DSA_TAG_YT921X is not set
CONFIG_VLAN_8021Q=y
CONFIG_VLAN_8021Q_GVRP=y
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_LLC=y
CONFIG_LLC2=y
CONFIG_X25=y
CONFIG_LAPB=y
CONFIG_PHONET=y
CONFIG_6LOWPAN=y
# CONFIG_6LOWPAN_DEBUGFS is not set
CONFIG_6LOWPAN_NHC=y
CONFIG_6LOWPAN_NHC_DEST=y
CONFIG_6LOWPAN_NHC_FRAGMENT=y
CONFIG_6LOWPAN_NHC_HOP=y
CONFIG_6LOWPAN_NHC_IPV6=y
CONFIG_6LOWPAN_NHC_MOBILITY=y
CONFIG_6LOWPAN_NHC_ROUTING=y
CONFIG_6LOWPAN_NHC_UDP=y
CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=y
CONFIG_6LOWPAN_GHC_UDP=y
CONFIG_6LOWPAN_GHC_ICMPV6=y
CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=y
CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=y
CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=y
CONFIG_IEEE802154=y
CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y
CONFIG_IEEE802154_SOCKET=y
CONFIG_IEEE802154_6LOWPAN=y
CONFIG_MAC802154=y
CONFIG_NET_SCHED=y

#
# Queueing/Scheduling
#
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_HFSC=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_RED=y
CONFIG_NET_SCH_SFB=y
CONFIG_NET_SCH_SFQ=y
CONFIG_NET_SCH_TEQL=y
CONFIG_NET_SCH_TBF=y
CONFIG_NET_SCH_CBS=y
CONFIG_NET_SCH_ETF=y
CONFIG_NET_SCH_MQPRIO_LIB=y
CONFIG_NET_SCH_TAPRIO=y
CONFIG_NET_SCH_GRED=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_DRR=y
CONFIG_NET_SCH_MQPRIO=y
CONFIG_NET_SCH_SKBPRIO=y
CONFIG_NET_SCH_CHOKE=y
CONFIG_NET_SCH_QFQ=y
CONFIG_NET_SCH_CODEL=y
CONFIG_NET_SCH_FQ_CODEL=y
CONFIG_NET_SCH_CAKE=y
CONFIG_NET_SCH_FQ=y
CONFIG_NET_SCH_HHF=y
CONFIG_NET_SCH_PIE=y
CONFIG_NET_SCH_FQ_PIE=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_SCH_PLUG=y
CONFIG_NET_SCH_ETS=y
# CONFIG_NET_SCH_DUALPI2 is not set
CONFIG_NET_SCH_DEFAULT=y
# CONFIG_DEFAULT_FQ is not set
CONFIG_DEFAULT_CODEL=y
# CONFIG_DEFAULT_FQ_CODEL is not set
# CONFIG_DEFAULT_FQ_PIE is not set
# CONFIG_DEFAULT_SFQ is not set
# CONFIG_DEFAULT_PFIFO_FAST is not set
CONFIG_DEFAULT_NET_SCH="pfifo_fast"

#
# Classification
#
CONFIG_NET_CLS=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_ROUTE4=y
CONFIG_NET_CLS_FW=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_PERF=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_CLS_CGROUP=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_FLOWER=y
CONFIG_NET_CLS_MATCHALL=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_STACK=32
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_EMATCH_CANID=y
CONFIG_NET_EMATCH_IPSET=y
CONFIG_NET_EMATCH_IPT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
CONFIG_NET_ACT_GACT=y
CONFIG_GACT_PROB=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SAMPLE=y
CONFIG_NET_ACT_NAT=y
CONFIG_NET_ACT_PEDIT=y
CONFIG_NET_ACT_SIMP=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_NET_ACT_CSUM=y
CONFIG_NET_ACT_MPLS=y
CONFIG_NET_ACT_VLAN=y
CONFIG_NET_ACT_BPF=y
CONFIG_NET_ACT_CONNMARK=y
CONFIG_NET_ACT_CTINFO=y
CONFIG_NET_ACT_SKBMOD=y
CONFIG_NET_ACT_IFE=y
CONFIG_NET_ACT_TUNNEL_KEY=y
CONFIG_NET_ACT_CT=y
CONFIG_NET_ACT_GATE=y
CONFIG_NET_IFE_SKBMARK=y
CONFIG_NET_IFE_SKBPRIO=y
CONFIG_NET_IFE_SKBTCINDEX=y
CONFIG_NET_TC_SKB_EXT=y
CONFIG_NET_SCH_FIFO=y
CONFIG_DCB=y
CONFIG_DNS_RESOLVER=y
CONFIG_BATMAN_ADV=y
CONFIG_BATMAN_ADV_BATMAN_V=y
CONFIG_BATMAN_ADV_BLA=y
CONFIG_BATMAN_ADV_DAT=y
CONFIG_BATMAN_ADV_MCAST=y
# CONFIG_BATMAN_ADV_DEBUG is not set
# CONFIG_BATMAN_ADV_TRACING is not set
CONFIG_OPENVSWITCH=y
CONFIG_OPENVSWITCH_GRE=y
CONFIG_OPENVSWITCH_VXLAN=y
CONFIG_OPENVSWITCH_GENEVE=y
CONFIG_VSOCKETS=y
CONFIG_VSOCKETS_DIAG=y
CONFIG_VSOCKETS_LOOPBACK=y
# CONFIG_VMWARE_VMCI_VSOCKETS is not set
CONFIG_VIRTIO_VSOCKETS=y
CONFIG_VIRTIO_VSOCKETS_COMMON=y
CONFIG_NETLINK_DIAG=y
CONFIG_MPLS=y
CONFIG_NET_MPLS_GSO=y
CONFIG_MPLS_ROUTING=y
CONFIG_MPLS_IPTUNNEL=y
CONFIG_NET_NSH=y
CONFIG_HSR=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_L3_MASTER_DEV=y
CONFIG_QRTR=y
CONFIG_QRTR_TUN=y
# CONFIG_QRTR_MHI is not set
CONFIG_NET_NCSI=y
# CONFIG_NCSI_OEM_CMD_GET_MAC is not set
# CONFIG_NCSI_OEM_CMD_KEEP_PHY is not set
# CONFIG_PCPU_DEV_REFCNT is not set
CONFIG_MAX_SKB_FRAGS=17
CONFIG_RPS=y
CONFIG_RFS_ACCEL=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_XPS=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y
CONFIG_NET_FLOW_LIMIT=y

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
CONFIG_NET_DROP_MONITOR=y
# end of Network testing
# end of Networking options

CONFIG_CAN=y
CONFIG_CAN_RAW=y
CONFIG_CAN_BCM=y
CONFIG_CAN_GW=y
CONFIG_CAN_J1939=y
CONFIG_CAN_ISOTP=y
CONFIG_BT=y
CONFIG_BT_BREDR=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=y
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=y
CONFIG_BT_LE=y
CONFIG_BT_LE_L2CAP_ECRED=y
CONFIG_BT_6LOWPAN=y
CONFIG_BT_LEDS=y
CONFIG_BT_MSFTEXT=y
# CONFIG_BT_AOSPEXT is not set
# CONFIG_BT_DEBUGFS is not set
# CONFIG_BT_SELFTEST is not set
# CONFIG_BT_FEATURE_DEBUG is not set

#
# Bluetooth device drivers
#
CONFIG_BT_INTEL=y
CONFIG_BT_BCM=y
CONFIG_BT_RTL=y
CONFIG_BT_QCA=y
CONFIG_BT_MTK=y
CONFIG_BT_HCIBTUSB=y
CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
CONFIG_BT_HCIBTUSB_POLL_SYNC=y
CONFIG_BT_HCIBTUSB_BCM=y
CONFIG_BT_HCIBTUSB_MTK=y
CONFIG_BT_HCIBTUSB_RTL=y
# CONFIG_BT_HCIBTSDIO is not set
CONFIG_BT_HCIUART=y
CONFIG_BT_HCIUART_SERDEV=y
CONFIG_BT_HCIUART_H4=y
# CONFIG_BT_HCIUART_NOKIA is not set
CONFIG_BT_HCIUART_BCSP=y
# CONFIG_BT_HCIUART_ATH3K is not set
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIUART_3WIRE=y
# CONFIG_BT_HCIUART_INTEL is not set
# CONFIG_BT_HCIUART_BCM is not set
# CONFIG_BT_HCIUART_RTL is not set
CONFIG_BT_HCIUART_QCA=y
CONFIG_BT_HCIUART_AG6XX=y
CONFIG_BT_HCIUART_MRVL=y
# CONFIG_BT_HCIUART_AML is not set
CONFIG_BT_HCIBCM203X=y
# CONFIG_BT_HCIBCM4377 is not set
CONFIG_BT_HCIBPA10X=y
CONFIG_BT_HCIBFUSB=y
CONFIG_BT_HCIVHCI=y
CONFIG_BT_MRVL=y
CONFIG_BT_MRVL_SDIO=y
CONFIG_BT_ATH3K=y
CONFIG_BT_MTKSDIO=y
CONFIG_BT_MTKUART=y
# CONFIG_BT_VIRTIO is not set
# CONFIG_BT_NXPUART is not set
# CONFIG_BT_INTEL_PCIE is not set
# end of Bluetooth device drivers

CONFIG_AF_RXRPC=y
CONFIG_AF_RXRPC_IPV6=y
# CONFIG_AF_RXRPC_INJECT_LOSS is not set
# CONFIG_AF_RXRPC_INJECT_RX_DELAY is not set
# CONFIG_AF_RXRPC_DEBUG is not set
CONFIG_RXKAD=y
# CONFIG_RXGK is not set
# CONFIG_RXPERF is not set
CONFIG_AF_KCM=y
CONFIG_STREAM_PARSER=y
CONFIG_MCTP=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_CFG80211=y
# CONFIG_NL80211_TESTMODE is not set
# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y
CONFIG_CFG80211_DEFAULT_PS=y
CONFIG_CFG80211_DEBUGFS=y
CONFIG_CFG80211_CRDA_SUPPORT=y
CONFIG_CFG80211_WEXT=y
CONFIG_MAC80211=y
CONFIG_MAC80211_HAS_RC=y
CONFIG_MAC80211_RC_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
CONFIG_MAC80211_MESH=y
CONFIG_MAC80211_LEDS=y
CONFIG_MAC80211_DEBUGFS=y
# CONFIG_MAC80211_MESSAGE_TRACING is not set
# CONFIG_MAC80211_DEBUG_MENU is not set
CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
CONFIG_RFKILL=y
CONFIG_RFKILL_LEDS=y
CONFIG_RFKILL_INPUT=y
# CONFIG_RFKILL_GPIO is not set
CONFIG_NET_9P=y
CONFIG_NET_9P_FD=y
CONFIG_NET_9P_VIRTIO=y
# CONFIG_NET_9P_USBG is not set
CONFIG_NET_9P_RDMA=y
# CONFIG_NET_9P_DEBUG is not set
CONFIG_CEPH_LIB=y
# CONFIG_CEPH_LIB_PRETTYDEBUG is not set
CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y
CONFIG_NFC=y
CONFIG_NFC_DIGITAL=y
CONFIG_NFC_NCI=y
# CONFIG_NFC_NCI_SPI is not set
CONFIG_NFC_NCI_UART=y
CONFIG_NFC_HCI=y
CONFIG_NFC_SHDLC=y

#
# Near Field Communication (NFC) devices
#
# CONFIG_NFC_TRF7970A is not set
# CONFIG_NFC_MEI_PHY is not set
CONFIG_NFC_SIM=y
CONFIG_NFC_PORT100=y
CONFIG_NFC_VIRTUAL_NCI=y
CONFIG_NFC_FDP=y
# CONFIG_NFC_FDP_I2C is not set
# CONFIG_NFC_PN544_I2C is not set
CONFIG_NFC_PN533=y
CONFIG_NFC_PN533_USB=y
# CONFIG_NFC_PN533_I2C is not set
# CONFIG_NFC_PN532_UART is not set
# CONFIG_NFC_MICROREAD_I2C is not set
CONFIG_NFC_MRVL=y
CONFIG_NFC_MRVL_USB=y
# CONFIG_NFC_MRVL_UART is not set
# CONFIG_NFC_MRVL_I2C is not set
# CONFIG_NFC_ST21NFCA_I2C is not set
# CONFIG_NFC_ST_NCI_I2C is not set
# CONFIG_NFC_ST_NCI_SPI is not set
# CONFIG_NFC_NXP_NCI is not set
# CONFIG_NFC_S3FWRN5_I2C is not set
# CONFIG_NFC_S3FWRN82_UART is not set
# CONFIG_NFC_ST95HF is not set
# end of Near Field Communication (NFC) devices

CONFIG_PSAMPLE=y
CONFIG_NET_IFE=y
CONFIG_LWTUNNEL=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_DST_CACHE=y
CONFIG_GRO_CELLS=y
CONFIG_SOCK_VALIDATE_XMIT=y
CONFIG_NET_SELFTESTS=y
CONFIG_NET_SOCK_MSG=y
CONFIG_NET_DEVLINK=y
CONFIG_PAGE_POOL=y
# CONFIG_PAGE_POOL_STATS is not set
CONFIG_FAILOVER=y
CONFIG_ETHTOOL_NETLINK=y

#
# Device Drivers
#
CONFIG_HAVE_PCI=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCIEPORTBUS=y
CONFIG_HOTPLUG_PCI_PCIE=y
CONFIG_PCIEAER=y
# CONFIG_PCIEAER_INJECT is not set
# CONFIG_PCIE_ECRC is not set
CONFIG_PCIEASPM=y
CONFIG_PCIEASPM_DEFAULT=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
# CONFIG_PCIEASPM_PERFORMANCE is not set
CONFIG_PCIE_PME=y
# CONFIG_PCIE_DPC is not set
# CONFIG_PCIE_PTM is not set
CONFIG_PCI_MSI=y
CONFIG_PCI_QUIRKS=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_PF_STUB is not set
CONFIG_PCI_ATS=y
# CONFIG_PCI_TSM is not set
# CONFIG_PCI_DOE is not set
CONFIG_PCI_ECAM=y
CONFIG_PCI_LOCKLESS_CONFIG=y
CONFIG_PCI_IOV=y
# CONFIG_PCI_NPEM is not set
CONFIG_PCI_PRI=y
CONFIG_PCI_PASID=y
# CONFIG_PCIE_TPH is not set
# CONFIG_PCI_P2PDMA is not set
CONFIG_PCI_LABEL=y
# CONFIG_PCI_DYNAMIC_OF_NODES is not set
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_ACPI is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
# CONFIG_HOTPLUG_PCI_OCTEONEP is not set
# CONFIG_HOTPLUG_PCI_SHPC is not set

#
# PCI controller drivers
#
CONFIG_PCI_HOST_COMMON=y
# CONFIG_PCI_FTPCI100 is not set
CONFIG_PCI_HOST_GENERIC=y
# CONFIG_VMD is not set
# CONFIG_PCIE_XILINX is not set

#
# Cadence-based PCIe controllers
#
# CONFIG_PCIE_CADENCE_PLAT_HOST is not set
# CONFIG_PCIE_CADENCE_PLAT_EP is not set
# end of Cadence-based PCIe controllers

#
# DesignWare-based PCIe controllers
#
# CONFIG_PCI_MESON is not set
# CONFIG_PCIE_INTEL_GW is not set
# CONFIG_PCIE_DW_PLAT_HOST is not set
# CONFIG_PCIE_DW_PLAT_EP is not set
# end of DesignWare-based PCIe controllers

#
# Mobiveil-based PCIe controllers
#
# end of Mobiveil-based PCIe controllers

#
# PLDA-based PCIe controllers
#
# CONFIG_PCIE_MICROCHIP_HOST is not set
# end of PLDA-based PCIe controllers
# end of PCI controller drivers

#
# PCI Endpoint
#
CONFIG_PCI_ENDPOINT=y
# CONFIG_PCI_ENDPOINT_CONFIGFS is not set
# CONFIG_PCI_ENDPOINT_MSI_DOORBELL is not set
# CONFIG_PCI_EPF_TEST is not set
# CONFIG_PCI_EPF_NTB is not set
# end of PCI Endpoint

#
# PCI switch controller drivers
#
# CONFIG_PCI_SW_SWITCHTEC is not set
# end of PCI switch controller drivers

# CONFIG_PCI_PWRCTRL_GENERIC is not set
# CONFIG_PCI_PWRCTRL_TC9563 is not set
# CONFIG_CXL_BUS is not set
CONFIG_PCCARD=y
CONFIG_PCMCIA=y
CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_CARDBUS=y

#
# PC-card bridges
#
CONFIG_YENTA=y
CONFIG_YENTA_O2=y
CONFIG_YENTA_RICOH=y
CONFIG_YENTA_TI=y
CONFIG_YENTA_ENE_TUNE=y
CONFIG_YENTA_TOSHIBA=y
# CONFIG_PD6729 is not set
CONFIG_PCCARD_NONSTATIC=y
# CONFIG_RAPIDIO is not set
# CONFIG_PC104 is not set

#
# Generic Driver Options
#
CONFIG_AUXILIARY_BUS=y
CONFIG_UEVENT_HELPER=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_DEVTMPFS_SAFE is not set
CONFIG_DRIVER_DEFERRED_PROBE_TIMEOUT=10
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y

#
# Firmware loader
#
CONFIG_FW_LOADER=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
CONFIG_FW_LOADER_COMPRESS=y
# CONFIG_FW_LOADER_COMPRESS_XZ is not set
# CONFIG_FW_LOADER_COMPRESS_ZSTD is not set
CONFIG_FW_CACHE=y
# CONFIG_FW_UPLOAD is not set
# end of Firmware loader

CONFIG_WANT_DEV_COREDUMP=y
CONFIG_ALLOW_DEV_COREDUMP=y
CONFIG_DEV_COREDUMP=y
# CONFIG_DEBUG_DRIVER is not set
CONFIG_DEBUG_DEVRES=y
# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_SPI=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_IRQ=y
CONFIG_DMA_SHARED_BUFFER=y
# CONFIG_DMA_FENCE_TRACE is not set
# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set
# end of Generic Driver Options

#
# Bus devices
#
# CONFIG_MOXTET is not set
CONFIG_MHI_BUS=y
# CONFIG_MHI_BUS_DEBUG is not set
# CONFIG_MHI_BUS_PCI_GENERIC is not set
# CONFIG_MHI_BUS_EP is not set
# end of Bus devices

CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y

#
# Firmware Drivers
#

#
# ARM System Control and Management Interface Protocol
#
# end of ARM System Control and Management Interface Protocol

# CONFIG_EDD is not set
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DMIID=y
# CONFIG_DMI_SYSFS is not set
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
# CONFIG_ISCSI_IBFT is not set
# CONFIG_FW_CFG_SYSFS is not set
CONFIG_SYSFB=y
# CONFIG_SYSFB_SIMPLEFB is not set
CONFIG_GOOGLE_FIRMWARE=y
# CONFIG_GOOGLE_SMI is not set
# CONFIG_GOOGLE_CBMEM is not set
CONFIG_GOOGLE_COREBOOT_TABLE=y
CONFIG_GOOGLE_MEMCONSOLE=y
# CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY is not set
# CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT is not set
CONFIG_GOOGLE_MEMCONSOLE_COREBOOT=y
CONFIG_GOOGLE_VPD=y

#
# Qualcomm firmware drivers
#
# end of Qualcomm firmware drivers

#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers

# CONFIG_FWCTL is not set
CONFIG_GNSS=y
# CONFIG_GNSS_MTK_SERIAL is not set
# CONFIG_GNSS_SIRF_SERIAL is not set
# CONFIG_GNSS_UBX_SERIAL is not set
CONFIG_GNSS_USB=y
CONFIG_MTD=y
# CONFIG_MTD_TESTS is not set

#
# Partition parsers
#
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_OF_PARTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# end of Partition parsers

#
# User Modules And Translation Layers
#
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y

#
# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK.
#
CONFIG_FTL=y
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
# CONFIG_MTD_SWAP is not set
# CONFIG_MTD_PARTITIONED_MASTER is not set

#
# RAM/ROM/Flash chip drivers
#
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
# end of RAM/ROM/Flash chip drivers

#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PLATRAM is not set
# end of Mapping drivers for chip access

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_MCHP23K256 is not set
# CONFIG_MTD_MCHP48L640 is not set
# CONFIG_MTD_SST25L is not set
CONFIG_MTD_SLRAM=y
CONFIG_MTD_PHRAM=y
CONFIG_MTD_MTDRAM=y
CONFIG_MTDRAM_TOTAL_SIZE=128
CONFIG_MTDRAM_ERASE_SIZE=4
CONFIG_MTD_BLOCK2MTD=y
# CONFIG_MTD_INTEL_DG is not set

#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOCG3 is not set
# end of Self-contained MTD device drivers

#
# NAND
#
# CONFIG_MTD_ONENAND is not set
# CONFIG_MTD_RAW_NAND is not set
# CONFIG_MTD_SPI_NAND is not set

#
# ECC engine support
#
# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set
# CONFIG_MTD_NAND_ECC_SW_BCH is not set
# CONFIG_MTD_NAND_ECC_MXIC is not set
# end of ECC engine support
# end of NAND

#
# LPDDR & LPDDR2 PCM memory drivers
#
# CONFIG_MTD_LPDDR is not set
# end of LPDDR & LPDDR2 PCM memory drivers

# CONFIG_MTD_SPI_NOR is not set
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_LIMIT=20
# CONFIG_MTD_UBI_FASTMAP is not set
# CONFIG_MTD_UBI_GLUEBI is not set
# CONFIG_MTD_UBI_BLOCK is not set
# CONFIG_MTD_UBI_FAULT_INJECTION is not set
# CONFIG_MTD_UBI_NVMEM is not set
# CONFIG_MTD_HYPERBUS is not set
CONFIG_DTC=y
CONFIG_OF=y
# CONFIG_OF_UNITTEST is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_KOBJ=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_RESERVED_MEM=y
# CONFIG_OF_OVERLAY is not set
CONFIG_OF_NUMA=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_PARPORT=y
# CONFIG_PARPORT_PC is not set
# CONFIG_PARPORT_1284 is not set
CONFIG_PARPORT_NOT_PC=y
CONFIG_PNP=y
CONFIG_PNP_DEBUG_MESSAGES=y

#
# Protocols
#
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_NULL_BLK=y
CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION=y
# CONFIG_BLK_DEV_FD is not set
CONFIG_CDROM=y
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
CONFIG_ZRAM=y
# CONFIG_ZRAM_BACKEND_LZ4 is not set
# CONFIG_ZRAM_BACKEND_LZ4HC is not set
# CONFIG_ZRAM_BACKEND_ZSTD is not set
# CONFIG_ZRAM_BACKEND_DEFLATE is not set
# CONFIG_ZRAM_BACKEND_842 is not set
CONFIG_ZRAM_BACKEND_FORCE_LZO=y
CONFIG_ZRAM_BACKEND_LZO=y
# CONFIG_ZRAM_DEF_COMP_LZORLE is not set
CONFIG_ZRAM_DEF_COMP_LZO=y
CONFIG_ZRAM_DEF_COMP="lzo"
# CONFIG_ZRAM_WRITEBACK is not set
# CONFIG_ZRAM_TRACK_ENTRY_ACTIME is not set
# CONFIG_ZRAM_MEMORY_TRACKING is not set
# CONFIG_ZRAM_MULTI_COMP is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16
# CONFIG_BLK_DEV_DRBD is not set
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_ATA_OVER_ETH=y
CONFIG_VIRTIO_BLK=y
# CONFIG_BLK_DEV_RBD is not set
CONFIG_BLK_DEV_UBLK=y
CONFIG_BLKDEV_UBLK_LEGACY_OPCODES=y
CONFIG_BLK_DEV_RNBD=y
CONFIG_BLK_DEV_RNBD_CLIENT=y
# CONFIG_BLK_DEV_ZONED_LOOP is not set

#
# NVME Support
#
CONFIG_NVME_CORE=y
CONFIG_BLK_DEV_NVME=y
CONFIG_NVME_MULTIPATH=y
# CONFIG_NVME_VERBOSE_ERRORS is not set
# CONFIG_NVME_HWMON is not set
CONFIG_NVME_FABRICS=y
CONFIG_NVME_RDMA=y
CONFIG_NVME_FC=y
CONFIG_NVME_TCP=y
# CONFIG_NVME_TCP_TLS is not set
# CONFIG_NVME_HOST_AUTH is not set
CONFIG_NVME_TARGET=y
# CONFIG_NVME_TARGET_DEBUGFS is not set
# CONFIG_NVME_TARGET_PASSTHRU is not set
CONFIG_NVME_TARGET_LOOP=y
CONFIG_NVME_TARGET_RDMA=y
CONFIG_NVME_TARGET_FC=y
CONFIG_NVME_TARGET_FCLOOP=y
CONFIG_NVME_TARGET_TCP=y
# CONFIG_NVME_TARGET_TCP_TLS is not set
# CONFIG_NVME_TARGET_AUTH is not set
# CONFIG_NVME_TARGET_PCI_EPF is not set
# end of NVME Support

#
# Misc devices
#
# CONFIG_AD525X_DPOT is not set
# CONFIG_DUMMY_IRQ is not set
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
# CONFIG_RPMB is not set
# CONFIG_TI_FPC202 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_APDS9802ALS is not set
# CONFIG_ISL29003 is not set
# CONFIG_ISL29020 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_SENSORS_BH1770 is not set
# CONFIG_HMC6352 is not set
# CONFIG_DS1682 is not set
# CONFIG_VMWARE_BALLOON is not set
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_SRAM is not set
# CONFIG_DW_XDATA_PCIE is not set
# CONFIG_PCI_ENDPOINT_TEST is not set
# CONFIG_XILINX_SDFEC is not set
CONFIG_MISC_RTSX=y
# CONFIG_HISI_HIKEY_USB is not set
# CONFIG_OPEN_DICE is not set
# CONFIG_NTSYNC is not set
# CONFIG_VCPU_STALL_DETECTOR is not set
# CONFIG_NSM is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_MAX6875 is not set
CONFIG_EEPROM_93CX6=y
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_EEPROM_IDT_89HPESX is not set
# CONFIG_EEPROM_EE1004 is not set
# CONFIG_EEPROM_M24LR is not set
# end of EEPROM support

# CONFIG_CB710_CORE is not set
# CONFIG_SENSORS_LIS3_I2C is not set
# CONFIG_ALTERA_STAPL is not set
CONFIG_INTEL_MEI=y
CONFIG_INTEL_MEI_ME=y
# CONFIG_INTEL_MEI_TXE is not set
# CONFIG_INTEL_MEI_GSC is not set
# CONFIG_INTEL_MEI_CSC is not set
# CONFIG_INTEL_MEI_VSC_HW is not set
# CONFIG_INTEL_MEI_HDCP is not set
# CONFIG_INTEL_MEI_PXP is not set
# CONFIG_INTEL_MEI_GSC_PROXY is not set
CONFIG_VMWARE_VMCI=y
# CONFIG_GENWQE is not set
# CONFIG_BCM_VK is not set
# CONFIG_MISC_ALCOR_PCI is not set
# CONFIG_MISC_RTSX_PCI is not set
CONFIG_MISC_RTSX_USB=y
# CONFIG_UACCE is not set
# CONFIG_PVPANIC is not set
# CONFIG_GP_PCI1XXXX is not set
# CONFIG_KEBA_CP500 is not set
# CONFIG_MISC_RP1 is not set
# end of Misc devices

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
CONFIG_RAID_ATTRS=y
CONFIG_SCSI_COMMON=y
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=y
CONFIG_BLK_DEV_BSG=y
# CONFIG_CHR_DEV_SCH is not set
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
CONFIG_SCSI_SAS_LIBSAS=y
CONFIG_SCSI_SAS_ATA=y
# CONFIG_SCSI_SAS_HOST_SMP is not set
CONFIG_SCSI_SRP_ATTRS=y
# end of SCSI Transports

CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_ISCSI_BOOT_SYSFS is not set
# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_SCSI_CXGB4_ISCSI is not set
# CONFIG_SCSI_BNX2_ISCSI is not set
# CONFIG_BE2ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
CONFIG_SCSI_HPSA=y
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_3W_SAS is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_MVUMI is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_SCSI_ESAS2R is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_MPT3SAS is not set
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_MPI3MR is not set
# CONFIG_SCSI_SMARTPQI is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_MYRB is not set
# CONFIG_SCSI_MYRS is not set
# CONFIG_VMWARE_PVSCSI is not set
# CONFIG_LIBFC is not set
# CONFIG_SCSI_SNIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FDOMAIN_PCI is not set
# CONFIG_SCSI_ISCI is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_EFCT is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_WD719X is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_PMCRAID is not set
# CONFIG_SCSI_PM8001 is not set
# CONFIG_SCSI_BFA_FC is not set
CONFIG_SCSI_VIRTIO=y
# CONFIG_SCSI_CHELSIO_FCOE is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
# end of SCSI device support

CONFIG_ATA=y
CONFIG_SATA_HOST=y
CONFIG_PATA_TIMINGS=y
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_FORCE=y
CONFIG_ATA_ACPI=y
# CONFIG_SATA_ZPODD is not set
CONFIG_SATA_PMP=y

#
# Controllers with non-SFF native interface
#
CONFIG_SATA_AHCI=y
CONFIG_SATA_MOBILE_LPM_POLICY=3
# CONFIG_SATA_AHCI_PLATFORM is not set
# CONFIG_AHCI_DWC is not set
# CONFIG_AHCI_CEVA is not set
# CONFIG_SATA_INIC162X is not set
# CONFIG_SATA_ACARD_AHCI is not set
# CONFIG_SATA_SIL24 is not set
CONFIG_ATA_SFF=y

#
# SFF controllers with custom DMA interface
#
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_SX4 is not set
CONFIG_ATA_BMDMA=y

#
# SATA SFF controllers with BMDMA
#
CONFIG_ATA_PIIX=y
# CONFIG_SATA_DWC is not set
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_SVW is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set

#
# PATA SFF controllers with BMDMA
#
# CONFIG_PATA_ALI is not set
CONFIG_PATA_AMD=y
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87415 is not set
CONFIG_PATA_OLDPIIX=y
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RDC is not set
CONFIG_PATA_SCH=y
# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_TOSHIBA is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set

#
# PIO-only SFF controllers
#
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_PCMCIA is not set
# CONFIG_PATA_OF_PLATFORM is not set
# CONFIG_PATA_RZ1000 is not set

#
# Generic fallback / legacy drivers
#
# CONFIG_PATA_ACPI is not set
CONFIG_ATA_GENERIC=y
# CONFIG_PATA_LEGACY is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_BITMAP=y
# CONFIG_MD_LLBITMAP is not set
CONFIG_MD_AUTODETECT=y
CONFIG_MD_BITMAP_FILE=y
# CONFIG_MD_LINEAR is not set
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
CONFIG_MD_RAID456=y
# CONFIG_MD_CLUSTER is not set
CONFIG_BCACHE=y
# CONFIG_BCACHE_DEBUG is not set
# CONFIG_BCACHE_ASYNC_REGISTRATION is not set
CONFIG_BLK_DEV_DM_BUILTIN=y
CONFIG_BLK_DEV_DM=y
# CONFIG_DM_DEBUG is not set
CONFIG_DM_BUFIO=y
# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set
CONFIG_DM_BIO_PRISON=y
CONFIG_DM_PERSISTENT_DATA=y
# CONFIG_DM_UNSTRIPED is not set
CONFIG_DM_CRYPT=y
# CONFIG_DM_INLINECRYPT is not set
CONFIG_DM_SNAPSHOT=y
CONFIG_DM_THIN_PROVISIONING=y
CONFIG_DM_CACHE=y
CONFIG_DM_CACHE_SMQ=y
CONFIG_DM_WRITECACHE=y
# CONFIG_DM_EBS is not set
# CONFIG_DM_ERA is not set
CONFIG_DM_CLONE=y
CONFIG_DM_MIRROR=y
# CONFIG_DM_LOG_USERSPACE is not set
CONFIG_DM_RAID=y
CONFIG_DM_ZERO=y
CONFIG_DM_MULTIPATH=y
CONFIG_DM_MULTIPATH_QL=y
CONFIG_DM_MULTIPATH_ST=y
# CONFIG_DM_MULTIPATH_HST is not set
# CONFIG_DM_MULTIPATH_IOA is not set
# CONFIG_DM_DELAY is not set
# CONFIG_DM_DUST is not set
# CONFIG_DM_INIT is not set
CONFIG_DM_UEVENT=y
CONFIG_DM_FLAKEY=y
CONFIG_DM_VERITY=y
# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set
CONFIG_DM_VERITY_FEC=y
# CONFIG_DM_SWITCH is not set
# CONFIG_DM_LOG_WRITES is not set
CONFIG_DM_INTEGRITY=y
CONFIG_DM_ZONED=y
CONFIG_DM_AUDIT=y
# CONFIG_DM_VDO is not set
# CONFIG_DM_PCACHE is not set
CONFIG_TARGET_CORE=y
# CONFIG_TCM_IBLOCK is not set
# CONFIG_TCM_FILEIO is not set
# CONFIG_TCM_PSCSI is not set
# CONFIG_LOOPBACK_TARGET is not set
# CONFIG_ISCSI_TARGET is not set
# CONFIG_SBP_TARGET is not set
# CONFIG_REMOTE_TARGET is not set
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#
CONFIG_FIREWIRE=y
CONFIG_FIREWIRE_OHCI=y
CONFIG_FIREWIRE_SBP2=y
CONFIG_FIREWIRE_NET=y
# CONFIG_FIREWIRE_NOSY is not set
# end of IEEE 1394 (FireWire) support

# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_MII=y
CONFIG_NET_CORE=y
CONFIG_BONDING=y
CONFIG_DUMMY=y
CONFIG_WIREGUARD=y
# CONFIG_WIREGUARD_DEBUG is not set
# CONFIG_OVPN is not set
CONFIG_EQUALIZER=y
CONFIG_NET_FC=y
CONFIG_IFB=y
CONFIG_NET_TEAM=y
CONFIG_NET_TEAM_MODE_BROADCAST=y
CONFIG_NET_TEAM_MODE_ROUNDROBIN=y
CONFIG_NET_TEAM_MODE_RANDOM=y
CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=y
CONFIG_NET_TEAM_MODE_LOADBALANCE=y
CONFIG_MACVLAN=y
CONFIG_MACVTAP=y
CONFIG_IPVLAN_L3S=y
CONFIG_IPVLAN=y
CONFIG_IPVTAP=y
CONFIG_VXLAN=y
CONFIG_GENEVE=y
CONFIG_BAREUDP=y
CONFIG_GTP=y
# CONFIG_PFCP is not set
# CONFIG_AMT is not set
CONFIG_MACSEC=y
CONFIG_NETCONSOLE=y
# CONFIG_NETCONSOLE_DYNAMIC is not set
# CONFIG_NETCONSOLE_EXTENDED_LOG is not set
CONFIG_NETPOLL=y
CONFIG_NET_POLL_CONTROLLER=y
CONFIG_TUN=y
CONFIG_TAP=y
CONFIG_TUN_VNET_CROSS_LE=y
CONFIG_VETH=y
CONFIG_VIRTIO_NET=y
CONFIG_NLMON=y
# CONFIG_NETKIT is not set
CONFIG_NET_VRF=y
CONFIG_VSOCKMON=y
# CONFIG_MHI_NET is not set
# CONFIG_ARCNET is not set
CONFIG_ATM_DRIVERS=y
# CONFIG_ATM_SOLOS is not set

#
# Distributed Switch Architecture drivers
#
# CONFIG_B53 is not set
# CONFIG_NET_DSA_BCM_SF2 is not set
# CONFIG_NET_DSA_LOOP is not set
# CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK is not set
# CONFIG_NET_DSA_LANTIQ_GSWIP is not set
# CONFIG_NET_DSA_MXL_GSW1XX is not set
# CONFIG_NET_DSA_MT7530 is not set
# CONFIG_NET_DSA_MV88E6060 is not set
# CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON is not set
# CONFIG_NET_DSA_MV88E6XXX is not set
# CONFIG_NET_DSA_MXL862 is not set
# CONFIG_NET_DSA_AR9331 is not set
# CONFIG_NET_DSA_QCA8K is not set
# CONFIG_NET_DSA_SJA1105 is not set
# CONFIG_NET_DSA_XRS700X_I2C is not set
# CONFIG_NET_DSA_XRS700X_MDIO is not set
# CONFIG_NET_DSA_REALTEK is not set
# CONFIG_NET_DSA_KS8995 is not set
# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set
# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set
# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set
# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set
# CONFIG_NET_DSA_YT921X is not set
# end of Distributed Switch Architecture drivers

CONFIG_ETHERNET=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_ADAPTEC is not set
# CONFIG_NET_VENDOR_AGERE is not set
# CONFIG_NET_VENDOR_ALACRITECH is not set
CONFIG_NET_VENDOR_ALIBABA=y
# CONFIG_ALIBABA_EEA is not set
# CONFIG_ALTERA_TSE is not set
CONFIG_NET_VENDOR_AMAZON=y
# CONFIG_ENA_ETHERNET is not set
# CONFIG_NET_VENDOR_AMD is not set
# CONFIG_NET_VENDOR_AQUANTIA is not set
# CONFIG_NET_VENDOR_ARC is not set
CONFIG_NET_VENDOR_ASIX=y
# CONFIG_SPI_AX88796C is not set
# CONFIG_NET_VENDOR_ATHEROS is not set
# CONFIG_CX_ECAT is not set
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_CADENCE is not set
# CONFIG_NET_VENDOR_CAVIUM is not set
# CONFIG_NET_VENDOR_CHELSIO is not set
CONFIG_NET_VENDOR_CISCO=y
# CONFIG_ENIC is not set
# CONFIG_NET_VENDOR_CORTINA is not set
CONFIG_NET_VENDOR_DAVICOM=y
# CONFIG_DM9051 is not set
# CONFIG_NET_VENDOR_DEC is not set
# CONFIG_NET_VENDOR_DLINK is not set
# CONFIG_NET_VENDOR_EMULEX is not set
CONFIG_NET_VENDOR_ENGLEDER=y
# CONFIG_TSNEP is not set
# CONFIG_NET_VENDOR_EZCHIP is not set
CONFIG_NET_VENDOR_FUNGIBLE=y
# CONFIG_FUN_ETH is not set
CONFIG_NET_VENDOR_GOOGLE=y
CONFIG_GVE=y
CONFIG_NET_VENDOR_HISILICON=y
# CONFIG_HIBMCGE is not set
# CONFIG_NET_VENDOR_HUAWEI is not set
CONFIG_NET_VENDOR_I825XX=y
CONFIG_NET_VENDOR_INTEL=y
CONFIG_E100=y
CONFIG_E1000=y
CONFIG_E1000E=y
CONFIG_E1000E_HWTS=y
# CONFIG_IGB is not set
# CONFIG_IGBVF is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not set
# CONFIG_I40E is not set
# CONFIG_I40EVF is not set
# CONFIG_ICE is not set
# CONFIG_FM10K is not set
# CONFIG_IGC is not set
# CONFIG_IDPF is not set
# CONFIG_JME is not set
# CONFIG_NET_VENDOR_ADI is not set
CONFIG_NET_VENDOR_LITEX=y
# CONFIG_LITEX_LITEETH is not set
# CONFIG_NET_VENDOR_MARVELL is not set
CONFIG_NET_VENDOR_MELLANOX=y
# CONFIG_MLX4_EN is not set
CONFIG_MLX4_CORE=y
# CONFIG_MLX4_DEBUG is not set
# CONFIG_MLX4_CORE_GEN2 is not set
# CONFIG_MLX5_CORE is not set
# CONFIG_MLXSW_CORE is not set
# CONFIG_MLXFW is not set
CONFIG_NET_VENDOR_META=y
# CONFIG_FBNIC is not set
# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_NET_VENDOR_MICROSEMI is not set
CONFIG_NET_VENDOR_MICROSOFT=y
CONFIG_NET_VENDOR_MUCSE=y
# CONFIG_MGBE is not set
# CONFIG_NET_VENDOR_MYRI is not set
# CONFIG_FEALNX is not set
# CONFIG_NET_VENDOR_NI is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_NVIDIA is not set
# CONFIG_NET_VENDOR_OKI is not set
# CONFIG_ETHOC is not set
# CONFIG_NET_VENDOR_PENSANDO is not set
# CONFIG_NET_VENDOR_QLOGIC is not set
# CONFIG_NET_VENDOR_BROCADE is not set
# CONFIG_NET_VENDOR_QUALCOMM is not set
# CONFIG_NET_VENDOR_RDC is not set
# CONFIG_NET_VENDOR_REALTEK is not set
# CONFIG_NET_VENDOR_RENESAS is not set
# CONFIG_NET_VENDOR_ROCKER is not set
# CONFIG_NET_VENDOR_SAMSUNG is not set
# CONFIG_NET_VENDOR_SEEQ is not set
# CONFIG_NET_VENDOR_SILAN is not set
# CONFIG_NET_VENDOR_SIS is not set
# CONFIG_NET_VENDOR_SOLARFLARE is not set
# CONFIG_NET_VENDOR_SMSC is not set
# CONFIG_NET_VENDOR_SOCIONEXT is not set
# CONFIG_NET_VENDOR_STMICRO is not set
# CONFIG_NET_VENDOR_SUN is not set
# CONFIG_NET_VENDOR_SYNOPSYS is not set
# CONFIG_NET_VENDOR_TEHUTI is not set
# CONFIG_NET_VENDOR_TI is not set
CONFIG_NET_VENDOR_VERTEXCOM=y
# CONFIG_MSE102X is not set
# CONFIG_NET_VENDOR_VIA is not set
CONFIG_NET_VENDOR_WANGXUN=y
# CONFIG_NGBE is not set
# CONFIG_TXGBE is not set
# CONFIG_TXGBEVF is not set
# CONFIG_NGBEVF is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_NET_VENDOR_XILINX is not set
# CONFIG_NET_VENDOR_XIRCOM is not set
CONFIG_FDDI=y
# CONFIG_DEFXX is not set
# CONFIG_SKFP is not set
CONFIG_PHYLINK=y
CONFIG_PHYLIB=y
CONFIG_SWPHY=y
CONFIG_PHY_PACKAGE=y
# CONFIG_LED_TRIGGER_PHY is not set
CONFIG_PHYLIB_LEDS=y
CONFIG_FIXED_PHY=y
# CONFIG_SFP is not set

#
# MII PHY device drivers
#
# CONFIG_AS21XXX_PHY is not set
# CONFIG_AIR_AN8801_PHY is not set
# CONFIG_AIR_EN8811H_PHY is not set
# CONFIG_AMD_PHY is not set
# CONFIG_ADIN_PHY is not set
# CONFIG_ADIN1100_PHY is not set
# CONFIG_AQUANTIA_PHY is not set
CONFIG_AX88796B_PHY=y
# CONFIG_BROADCOM_PHY is not set
# CONFIG_BCM54140_PHY is not set
# CONFIG_BCM7XXX_PHY is not set
# CONFIG_BCM84881_PHY is not set
# CONFIG_BCM87XX_PHY is not set
# CONFIG_CICADA_PHY is not set
# CONFIG_CORTINA_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_LXT_PHY is not set
# CONFIG_INTEL_XWAY_PHY is not set
# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_MARVELL_PHY is not set
# CONFIG_MARVELL_10G_PHY is not set
# CONFIG_MARVELL_88Q2XXX_PHY is not set
# CONFIG_MARVELL_88X2222_PHY is not set
# CONFIG_MAXLINEAR_GPHY is not set
# CONFIG_MAXLINEAR_86110_PHY is not set
# CONFIG_MEDIATEK_GE_PHY is not set
# CONFIG_MICREL_PHY is not set
# CONFIG_MICROCHIP_T1S_PHY is not set
CONFIG_MICROCHIP_PHY=y
# CONFIG_MICROCHIP_T1_PHY is not set
# CONFIG_MICROSEMI_PHY is not set
# CONFIG_MOTORCOMM_PHY is not set
# CONFIG_NATIONAL_PHY is not set
# CONFIG_NXP_CBTX_PHY is not set
# CONFIG_NXP_C45_TJA11XX_PHY is not set
# CONFIG_NXP_TJA11XX_PHY is not set
# CONFIG_NCN26000_PHY is not set
# CONFIG_AT803X_PHY is not set
# CONFIG_QCA83XX_PHY is not set
# CONFIG_QCA808X_PHY is not set
# CONFIG_QCA807X_PHY is not set
# CONFIG_QSEMI_PHY is not set
CONFIG_REALTEK_PHY=y
# CONFIG_REALTEK_PHY_HWMON is not set
# CONFIG_RENESAS_PHY is not set
# CONFIG_ROCKCHIP_PHY is not set
CONFIG_SMSC_PHY=y
# CONFIG_STE10XP is not set
# CONFIG_TERANETICS_PHY is not set
# CONFIG_DP83822_PHY is not set
# CONFIG_DP83TC811_PHY is not set
# CONFIG_DP83848_PHY is not set
# CONFIG_DP83867_PHY is not set
# CONFIG_DP83869_PHY is not set
# CONFIG_DP83TD510_PHY is not set
# CONFIG_DP83TG720_PHY is not set
# CONFIG_VITESSE_PHY is not set
# CONFIG_XILINX_GMII2RGMII is not set
# CONFIG_PSE_CONTROLLER is not set
CONFIG_CAN_DEV=y
CONFIG_CAN_VCAN=y
CONFIG_CAN_VXCAN=y
CONFIG_CAN_NETLINK=y
CONFIG_CAN_CALC_BITTIMING=y
CONFIG_CAN_RX_OFFLOAD=y
# CONFIG_CAN_CAN327 is not set
# CONFIG_CAN_DUMMY is not set
# CONFIG_CAN_FLEXCAN is not set
# CONFIG_CAN_GRCAN is not set
# CONFIG_CAN_KVASER_PCIEFD is not set
CONFIG_CAN_SLCAN=y
# CONFIG_CAN_VIRTIO_CAN is not set
# CONFIG_CAN_C_CAN is not set
# CONFIG_CAN_CC770 is not set
# CONFIG_CAN_CTUCANFD_PCI is not set
# CONFIG_CAN_CTUCANFD_PLATFORM is not set
# CONFIG_CAN_ESD_402_PCI is not set
CONFIG_CAN_IFI_CANFD=y
# CONFIG_CAN_M_CAN is not set
# CONFIG_CAN_PEAK_PCIEFD is not set
# CONFIG_CAN_SJA1000 is not set
# CONFIG_CAN_SOFTING is not set

#
# CAN SPI interfaces
#
# CONFIG_CAN_HI311X is not set
# CONFIG_CAN_MCP251X is not set
# CONFIG_CAN_MCP251XFD is not set
# end of CAN SPI interfaces

#
# CAN USB interfaces
#
CONFIG_CAN_8DEV_USB=y
CONFIG_CAN_EMS_USB=y
CONFIG_CAN_ESD_USB=y
CONFIG_CAN_ETAS_ES58X=y
CONFIG_CAN_F81604=y
CONFIG_CAN_GS_USB=y
CONFIG_CAN_KVASER_USB=y
CONFIG_CAN_MCBA_USB=y
CONFIG_CAN_PEAK_USB=y
CONFIG_CAN_UCAN=y
# end of CAN USB interfaces

# CONFIG_CAN_DEBUG_DEVICES is not set

#
# MCTP Device Drivers
#
# CONFIG_MCTP_SERIAL is not set
# CONFIG_MCTP_TRANSPORT_I2C is not set
# CONFIG_MCTP_TRANSPORT_USB is not set
# end of MCTP Device Drivers

CONFIG_FWNODE_MDIO=y
CONFIG_OF_MDIO=y
CONFIG_ACPI_MDIO=y
# CONFIG_MDIO_BITBANG is not set
# CONFIG_MDIO_BCM_UNIMAC is not set
# CONFIG_MDIO_HISI_FEMAC is not set
CONFIG_MDIO_MVUSB=y
# CONFIG_MDIO_MSCC_MIIM is not set
# CONFIG_MDIO_OCTEON is not set
# CONFIG_MDIO_IPQ4019 is not set
# CONFIG_MDIO_IPQ8064 is not set
# CONFIG_MDIO_THUNDER is not set

#
# MDIO Multiplexers
#
# CONFIG_MDIO_BUS_MUX_GPIO is not set
# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set
# CONFIG_MDIO_BUS_MUX_MMIOREG is not set

#
# PCS device drivers
#
# CONFIG_PCS_XPCS is not set
# end of PCS device drivers

# CONFIG_PLIP is not set
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=y
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOATM=y
CONFIG_PPPOX=y
CONFIG_PPPOE=y
CONFIG_PPPOE_HASH_BITS_1=y
# CONFIG_PPPOE_HASH_BITS_2 is not set
# CONFIG_PPPOE_HASH_BITS_4 is not set
# CONFIG_PPPOE_HASH_BITS_8 is not set
CONFIG_PPPOE_HASH_BITS=1
CONFIG_PPTP=y
CONFIG_PPPOL2TP=y
CONFIG_PPP_ASYNC=y
CONFIG_PPP_SYNC_TTY=y
CONFIG_SLIP=y
CONFIG_SLHC=y
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
CONFIG_USB_NET_DRIVERS=y
CONFIG_USB_CATC=y
CONFIG_USB_KAWETH=y
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8150=y
CONFIG_USB_RTL8152=y
CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_AX8817X=y
CONFIG_USB_NET_AX88179_178A=y
CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_NET_CDC_EEM=y
CONFIG_USB_NET_CDC_NCM=y
CONFIG_USB_NET_HUAWEI_CDC_NCM=y
CONFIG_USB_NET_CDC_MBIM=y
CONFIG_USB_NET_DM9601=y
CONFIG_USB_NET_SR9700=y
CONFIG_USB_NET_SR9800=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_USB_NET_GL620A=y
CONFIG_USB_NET_NET1080=y
CONFIG_USB_NET_PLUSB=y
CONFIG_USB_NET_MCS7830=y
CONFIG_USB_NET_RNDIS_HOST=y
CONFIG_USB_NET_CDC_SUBSET_ENABLE=y
CONFIG_USB_NET_CDC_SUBSET=y
CONFIG_USB_ALI_M5632=y
CONFIG_USB_AN2720=y
CONFIG_USB_BELKIN=y
CONFIG_USB_ARMLINUX=y
CONFIG_USB_EPSON2888=y
CONFIG_USB_KC2190=y
CONFIG_USB_NET_ZAURUS=y
CONFIG_USB_NET_CX82310_ETH=y
CONFIG_USB_NET_KALMIA=y
CONFIG_USB_NET_QMI_WWAN=y
CONFIG_USB_HSO=y
CONFIG_USB_NET_INT51X1=y
CONFIG_USB_CDC_PHONET=y
CONFIG_USB_IPHETH=y
CONFIG_USB_SIERRA_NET=y
CONFIG_USB_VL600=y
CONFIG_USB_NET_CH9200=y
CONFIG_USB_NET_AQC111=y
CONFIG_USB_RTL8153_ECM=y
CONFIG_WLAN=y
CONFIG_WLAN_VENDOR_ADMTEK=y
# CONFIG_ADM8211 is not set
CONFIG_ATH_COMMON=y
CONFIG_WLAN_VENDOR_ATH=y
# CONFIG_ATH_DEBUG is not set
# CONFIG_ATH5K is not set
# CONFIG_ATH5K_PCI is not set
CONFIG_ATH9K_HW=y
CONFIG_ATH9K_COMMON=y
CONFIG_ATH9K_COMMON_DEBUG=y
CONFIG_ATH9K_BTCOEX_SUPPORT=y
CONFIG_ATH9K=y
CONFIG_ATH9K_PCI=y
CONFIG_ATH9K_AHB=y
CONFIG_ATH9K_DEBUGFS=y
# CONFIG_ATH9K_STATION_STATISTICS is not set
CONFIG_ATH9K_DYNACK=y
# CONFIG_ATH9K_WOW is not set
CONFIG_ATH9K_RFKILL=y
CONFIG_ATH9K_CHANNEL_CONTEXT=y
CONFIG_ATH9K_PCOEM=y
# CONFIG_ATH9K_PCI_NO_EEPROM is not set
CONFIG_ATH9K_HTC=y
CONFIG_ATH9K_HTC_DEBUGFS=y
# CONFIG_ATH9K_HWRNG is not set
CONFIG_ATH9K_COMMON_SPECTRAL=y
CONFIG_CARL9170=y
CONFIG_CARL9170_LEDS=y
# CONFIG_CARL9170_DEBUGFS is not set
CONFIG_CARL9170_WPC=y
CONFIG_CARL9170_HWRNG=y
CONFIG_ATH6KL=y
# CONFIG_ATH6KL_SDIO is not set
CONFIG_ATH6KL_USB=y
# CONFIG_ATH6KL_DEBUG is not set
# CONFIG_ATH6KL_TRACING is not set
CONFIG_AR5523=y
# CONFIG_WIL6210 is not set
CONFIG_ATH10K=y
CONFIG_ATH10K_CE=y
CONFIG_ATH10K_PCI=y
# CONFIG_ATH10K_AHB is not set
# CONFIG_ATH10K_SDIO is not set
CONFIG_ATH10K_USB=y
# CONFIG_ATH10K_DEBUG is not set
# CONFIG_ATH10K_DEBUGFS is not set
CONFIG_ATH10K_LEDS=y
# CONFIG_ATH10K_TRACING is not set
# CONFIG_WCN36XX is not set
CONFIG_ATH11K=y
# CONFIG_ATH11K_PCI is not set
# CONFIG_ATH11K_DEBUG is not set
# CONFIG_ATH11K_DEBUGFS is not set
# CONFIG_ATH11K_TRACING is not set
# CONFIG_ATH12K is not set
# CONFIG_WLAN_VENDOR_ATMEL is not set
# CONFIG_WLAN_VENDOR_BROADCOM is not set
# CONFIG_WLAN_VENDOR_INTEL is not set
# CONFIG_WLAN_VENDOR_INTERSIL is not set
# CONFIG_WLAN_VENDOR_MARVELL is not set
# CONFIG_WLAN_VENDOR_MEDIATEK is not set
# CONFIG_WLAN_VENDOR_MICROCHIP is not set
CONFIG_WLAN_VENDOR_PURELIFI=y
CONFIG_PLFXLC=y
# CONFIG_WLAN_VENDOR_RALINK is not set
# CONFIG_WLAN_VENDOR_REALTEK is not set
# CONFIG_WLAN_VENDOR_RSI is not set
CONFIG_WLAN_VENDOR_SILABS=y
# CONFIG_WFX is not set
# CONFIG_WLAN_VENDOR_ST is not set
# CONFIG_WLAN_VENDOR_TI is not set
# CONFIG_WLAN_VENDOR_ZYDAS is not set
# CONFIG_WLAN_VENDOR_QUANTENNA is not set
CONFIG_MAC80211_HWSIM=y
CONFIG_VIRT_WIFI=y
CONFIG_WAN=y
CONFIG_HDLC=y
CONFIG_HDLC_RAW=y
CONFIG_HDLC_RAW_ETH=y
CONFIG_HDLC_CISCO=y
CONFIG_HDLC_FR=y
CONFIG_HDLC_PPP=y
CONFIG_HDLC_X25=y
# CONFIG_FRAMER is not set
# CONFIG_PCI200SYN is not set
# CONFIG_WANXL is not set
# CONFIG_PC300TOO is not set
# CONFIG_FARSYNC is not set
CONFIG_LAPBETHER=y
CONFIG_IEEE802154_DRIVERS=y
# CONFIG_IEEE802154_FAKELB is not set
# CONFIG_IEEE802154_AT86RF230 is not set
# CONFIG_IEEE802154_MRF24J40 is not set
# CONFIG_IEEE802154_CC2520 is not set
CONFIG_IEEE802154_ATUSB=y
# CONFIG_IEEE802154_ADF7242 is not set
# CONFIG_IEEE802154_CA8210 is not set
# CONFIG_IEEE802154_MCR20A is not set
CONFIG_IEEE802154_HWSIM=y

#
# Wireless WAN
#
CONFIG_WWAN=y
# CONFIG_WWAN_DEBUGFS is not set
# CONFIG_WWAN_HWSIM is not set
CONFIG_MHI_WWAN_CTRL=y
# CONFIG_MHI_WWAN_MBIM is not set
# CONFIG_IOSM is not set
# CONFIG_MTK_T7XX is not set
# end of Wireless WAN

CONFIG_VMXNET3=y
# CONFIG_FUJITSU_ES is not set
CONFIG_USB4_NET=y
CONFIG_NETDEVSIM=y
CONFIG_NET_FAILOVER=y

#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_LEDS=y
CONFIG_INPUT_FF_MEMLESS=y
CONFIG_INPUT_SPARSEKMAP=y
# CONFIG_INPUT_MATRIXKMAP is not set
CONFIG_INPUT_VIVALDIFMAP=y

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ADC is not set
# CONFIG_KEYBOARD_ADP5588 is not set
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_QT1050 is not set
# CONFIG_KEYBOARD_QT1070 is not set
# CONFIG_KEYBOARD_QT2160 is not set
# CONFIG_KEYBOARD_DLINK_DIR685 is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_GPIO_POLLED is not set
# CONFIG_KEYBOARD_TCA8418 is not set
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_KEYBOARD_CHARLIEPLEX is not set
# CONFIG_KEYBOARD_LM8323 is not set
# CONFIG_KEYBOARD_LM8333 is not set
# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_MPR121 is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_PINEPHONE is not set
# CONFIG_KEYBOARD_SAMSUNG is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_OMAP4 is not set
# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set
# CONFIG_KEYBOARD_TWL4030 is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_CAP11XX is not set
# CONFIG_KEYBOARD_BCM is not set
# CONFIG_KEYBOARD_CYPRESS_SF is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_BYD=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
CONFIG_MOUSE_PS2_CYPRESS=y
CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
# CONFIG_MOUSE_PS2_SENTELIC is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_PS2_FOCALTECH=y
# CONFIG_MOUSE_PS2_VMMOUSE is not set
CONFIG_MOUSE_PS2_SMBUS=y
# CONFIG_MOUSE_SERIAL is not set
CONFIG_MOUSE_APPLETOUCH=y
CONFIG_MOUSE_BCM5974=y
# CONFIG_MOUSE_CYAPA is not set
# CONFIG_MOUSE_ELAN_I2C is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_MOUSE_GPIO is not set
# CONFIG_MOUSE_SYNAPTICS_I2C is not set
CONFIG_MOUSE_SYNAPTICS_USB=y
CONFIG_INPUT_JOYSTICK=y
# CONFIG_JOYSTICK_ANALOG is not set
# CONFIG_JOYSTICK_A3D is not set
# CONFIG_JOYSTICK_ADC is not set
# CONFIG_JOYSTICK_ADI is not set
# CONFIG_JOYSTICK_COBRA is not set
# CONFIG_JOYSTICK_GF2K is not set
# CONFIG_JOYSTICK_GRIP is not set
# CONFIG_JOYSTICK_GRIP_MP is not set
# CONFIG_JOYSTICK_GUILLEMOT is not set
# CONFIG_JOYSTICK_INTERACT is not set
# CONFIG_JOYSTICK_SIDEWINDER is not set
# CONFIG_JOYSTICK_TMDC is not set
CONFIG_JOYSTICK_IFORCE=y
CONFIG_JOYSTICK_IFORCE_USB=y
# CONFIG_JOYSTICK_IFORCE_232 is not set
# CONFIG_JOYSTICK_WARRIOR is not set
# CONFIG_JOYSTICK_MAGELLAN is not set
# CONFIG_JOYSTICK_SPACEORB is not set
# CONFIG_JOYSTICK_SPACEBALL is not set
# CONFIG_JOYSTICK_STINGER is not set
# CONFIG_JOYSTICK_TWIDJOY is not set
# CONFIG_JOYSTICK_ZHENHUA is not set
# CONFIG_JOYSTICK_DB9 is not set
# CONFIG_JOYSTICK_GAMECON is not set
# CONFIG_JOYSTICK_TURBOGRAFX is not set
# CONFIG_JOYSTICK_AS5011 is not set
# CONFIG_JOYSTICK_JOYDUMP is not set
CONFIG_JOYSTICK_XPAD=y
CONFIG_JOYSTICK_XPAD_FF=y
CONFIG_JOYSTICK_XPAD_LEDS=y
# CONFIG_JOYSTICK_WALKERA0701 is not set
# CONFIG_JOYSTICK_PSXPAD_SPI is not set
CONFIG_JOYSTICK_PXRC=y
# CONFIG_JOYSTICK_QWIIC is not set
# CONFIG_JOYSTICK_FSIA6B is not set
# CONFIG_JOYSTICK_SENSEHAT is not set
# CONFIG_JOYSTICK_SEESAW is not set
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=y
CONFIG_TABLET_USB_AIPTEK=y
CONFIG_TABLET_USB_HANWANG=y
CONFIG_TABLET_USB_KBTAB=y
CONFIG_TABLET_USB_PEGASUS=y
# CONFIG_TABLET_SERIAL_WACOM4 is not set
CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_ADS7846 is not set
# CONFIG_TOUCHSCREEN_AD7877 is not set
# CONFIG_TOUCHSCREEN_AD7879 is not set
# CONFIG_TOUCHSCREEN_ADC is not set
# CONFIG_TOUCHSCREEN_AR1021_I2C is not set
# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
# CONFIG_TOUCHSCREEN_BU21013 is not set
# CONFIG_TOUCHSCREEN_BU21029 is not set
# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set
# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set
# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set
# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
# CONFIG_TOUCHSCREEN_CYTTSP5 is not set
# CONFIG_TOUCHSCREEN_DYNAPRO is not set
# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
# CONFIG_TOUCHSCREEN_EETI is not set
# CONFIG_TOUCHSCREEN_EGALAX is not set
# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set
# CONFIG_TOUCHSCREEN_EXC3000 is not set
# CONFIG_TOUCHSCREEN_FUJITSU is not set
# CONFIG_TOUCHSCREEN_GOODIX is not set
# CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C is not set
# CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI is not set
# CONFIG_TOUCHSCREEN_HIDEEP is not set
# CONFIG_TOUCHSCREEN_HIMAX_HX852X is not set
# CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set
# CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX is not set
# CONFIG_TOUCHSCREEN_HYNITRON_CST816X is not set
# CONFIG_TOUCHSCREEN_ILI210X is not set
# CONFIG_TOUCHSCREEN_ILITEK is not set
# CONFIG_TOUCHSCREEN_S6SY761 is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_EKTF2127 is not set
# CONFIG_TOUCHSCREEN_ELAN is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
# CONFIG_TOUCHSCREEN_WACOM_I2C is not set
# CONFIG_TOUCHSCREEN_WACOM_W9000 is not set
# CONFIG_TOUCHSCREEN_MAX11801 is not set
# CONFIG_TOUCHSCREEN_MMS114 is not set
# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set
# CONFIG_TOUCHSCREEN_MSG2638 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS is not set
# CONFIG_TOUCHSCREEN_IMAGIS is not set
# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set
# CONFIG_TOUCHSCREEN_INEXIO is not set
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_PIXCIR is not set
# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set
CONFIG_TOUCHSCREEN_USB_COMPOSITE=y
CONFIG_TOUCHSCREEN_USB_EGALAX=y
CONFIG_TOUCHSCREEN_USB_PANJIT=y
CONFIG_TOUCHSCREEN_USB_3M=y
CONFIG_TOUCHSCREEN_USB_ITM=y
CONFIG_TOUCHSCREEN_USB_ETURBO=y
CONFIG_TOUCHSCREEN_USB_GUNZE=y
CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
CONFIG_TOUCHSCREEN_USB_GOTOP=y
CONFIG_TOUCHSCREEN_USB_JASTEC=y
CONFIG_TOUCHSCREEN_USB_ELO=y
CONFIG_TOUCHSCREEN_USB_E2I=y
CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y
CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y
CONFIG_TOUCHSCREEN_USB_NEXIO=y
CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
# CONFIG_TOUCHSCREEN_TSC2004 is not set
# CONFIG_TOUCHSCREEN_TSC2005 is not set
# CONFIG_TOUCHSCREEN_TSC2007 is not set
# CONFIG_TOUCHSCREEN_RM_TS is not set
# CONFIG_TOUCHSCREEN_SILEAD is not set
# CONFIG_TOUCHSCREEN_SIS_I2C is not set
# CONFIG_TOUCHSCREEN_ST1232 is not set
# CONFIG_TOUCHSCREEN_STMFTS is not set
CONFIG_TOUCHSCREEN_SUR40=y
# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set
# CONFIG_TOUCHSCREEN_SX8654 is not set
# CONFIG_TOUCHSCREEN_TPS6507X is not set
# CONFIG_TOUCHSCREEN_ZET6223 is not set
# CONFIG_TOUCHSCREEN_ZFORCE is not set
# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set
# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
# CONFIG_TOUCHSCREEN_IQS5XX is not set
# CONFIG_TOUCHSCREEN_IQS7211 is not set
# CONFIG_TOUCHSCREEN_ZINITIX is not set
# CONFIG_TOUCHSCREEN_HIMAX_HX83112B is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_AD714X is not set
# CONFIG_INPUT_ATMEL_CAPTOUCH is not set
# CONFIG_INPUT_AW86927 is not set
# CONFIG_INPUT_BMA150 is not set
# CONFIG_INPUT_E3X0_BUTTON is not set
# CONFIG_INPUT_PCSPKR is not set
# CONFIG_INPUT_MMA8450 is not set
# CONFIG_INPUT_APANEL is not set
# CONFIG_INPUT_GPIO_BEEPER is not set
# CONFIG_INPUT_GPIO_DECODER is not set
# CONFIG_INPUT_GPIO_VIBRA is not set
# CONFIG_INPUT_ATLAS_BTNS is not set
CONFIG_INPUT_ATI_REMOTE2=y
CONFIG_INPUT_KEYSPAN_REMOTE=y
# CONFIG_INPUT_KXTJ9 is not set
CONFIG_INPUT_POWERMATE=y
CONFIG_INPUT_YEALINK=y
CONFIG_INPUT_CM109=y
# CONFIG_INPUT_REGULATOR_HAPTIC is not set
# CONFIG_INPUT_RETU_PWRBUTTON is not set
# CONFIG_INPUT_TWL4030_PWRBUTTON is not set
# CONFIG_INPUT_TWL4030_VIBRA is not set
CONFIG_INPUT_UINPUT=y
# CONFIG_INPUT_PCF8574 is not set
# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
# CONFIG_INPUT_DA7280_HAPTICS is not set
# CONFIG_INPUT_ADXL34X is not set
# CONFIG_INPUT_IBM_PANEL is not set
CONFIG_INPUT_IMS_PCU=y
# CONFIG_INPUT_IQS269A is not set
# CONFIG_INPUT_IQS626A is not set
# CONFIG_INPUT_IQS7222 is not set
# CONFIG_INPUT_CMA3000 is not set
# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set
# CONFIG_INPUT_DRV260X_HAPTICS is not set
# CONFIG_INPUT_DRV2665_HAPTICS is not set
# CONFIG_INPUT_DRV2667_HAPTICS is not set
CONFIG_RMI4_CORE=y
# CONFIG_RMI4_I2C is not set
# CONFIG_RMI4_SPI is not set
# CONFIG_RMI4_SMB is not set
CONFIG_RMI4_F03=y
CONFIG_RMI4_F03_SERIO=y
CONFIG_RMI4_2D_SENSOR=y
CONFIG_RMI4_F11=y
CONFIG_RMI4_F12=y
# CONFIG_RMI4_F1A is not set
# CONFIG_RMI4_F21 is not set
CONFIG_RMI4_F30=y
# CONFIG_RMI4_F34 is not set
CONFIG_RMI4_F3A=y
# CONFIG_RMI4_F54 is not set
# CONFIG_RMI4_F55 is not set

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_PARKBD is not set
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_SERIO_ALTERA_PS2 is not set
# CONFIG_SERIO_PS2MULT is not set
# CONFIG_SERIO_ARC_PS2 is not set
# CONFIG_SERIO_APBPS2 is not set
# CONFIG_SERIO_GPIO_PS2 is not set
CONFIG_USERIO=y
# CONFIG_GAMEPORT is not set
# end of Hardware I/O ports
# end of Input device support

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LEGACY_TIOCSTI=y
CONFIG_LDISC_AUTOLOAD=y

#
# Serial drivers
#
CONFIG_SERIAL_EARLYCON=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_PNP=y
# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
# CONFIG_SERIAL_8250_FINTEK is not set
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_PCILIB=y
CONFIG_SERIAL_8250_PCI=y
# CONFIG_SERIAL_8250_EXAR is not set
# CONFIG_SERIAL_8250_CS is not set
CONFIG_SERIAL_8250_NR_UARTS=32
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_MANY_PORTS=y
# CONFIG_SERIAL_8250_PCI1XXXX is not set
# CONFIG_SERIAL_8250_DW is not set
# CONFIG_SERIAL_8250_RT288X is not set
CONFIG_SERIAL_8250_LPSS=y
CONFIG_SERIAL_8250_MID=y
CONFIG_SERIAL_8250_PERICOM=y
# CONFIG_SERIAL_8250_NI is not set
# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_SERIAL_8250_DWLIB=y

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
# CONFIG_SERIAL_UARTLITE is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_SIFIVE is not set
# CONFIG_SERIAL_LANTIQ is not set
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_SC16IS7XX is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_XILINX_PS_UART is not set
# CONFIG_SERIAL_ARC is not set
# CONFIG_SERIAL_RP2 is not set
# CONFIG_SERIAL_FSL_LPUART is not set
# CONFIG_SERIAL_FSL_LINFLEXUART is not set
# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
# CONFIG_SERIAL_SPRD is not set
# end of Serial drivers

CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not set
CONFIG_N_HDLC=y
# CONFIG_IPWIRELESS is not set
CONFIG_N_GSM=y
CONFIG_NOZOMI=y
CONFIG_NULL_TTY=y
CONFIG_HVC_DRIVER=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
CONFIG_TTY_PRINTK=y
CONFIG_TTY_PRINTK_LEVEL=6
# CONFIG_PRINTER is not set
# CONFIG_PPDEV is not set
CONFIG_VIRTIO_CONSOLE=y
# CONFIG_IPMI_HANDLER is not set
# CONFIG_SSIF_IPMI_BMC is not set
# CONFIG_IPMB_DEVICE_INTERFACE is not set
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_HW_RANDOM_INTEL is not set
# CONFIG_HW_RANDOM_AMD is not set
# CONFIG_HW_RANDOM_BA431 is not set
# CONFIG_HW_RANDOM_VIA is not set
CONFIG_HW_RANDOM_VIRTIO=y
# CONFIG_HW_RANDOM_CCTRNG is not set
# CONFIG_HW_RANDOM_XIPHERA is not set
# CONFIG_DEVMEM is not set
CONFIG_NVRAM=y
# CONFIG_DEVPORT is not set
CONFIG_HPET=y
CONFIG_HPET_MMAP=y
CONFIG_HPET_MMAP_DEFAULT=y
# CONFIG_HANGCHECK_TIMER is not set
CONFIG_TCG_TPM=y
# CONFIG_TCG_TPM2_HMAC is not set
# CONFIG_HW_RANDOM_TPM is not set
CONFIG_TCG_TIS_CORE=y
CONFIG_TCG_TIS=y
# CONFIG_TCG_TIS_SPI is not set
# CONFIG_TCG_TIS_I2C is not set
# CONFIG_TCG_TIS_I2C_CR50 is not set
# CONFIG_TCG_TIS_I2C_ATMEL is not set
# CONFIG_TCG_TIS_I2C_INFINEON is not set
# CONFIG_TCG_TIS_I2C_NUVOTON is not set
# CONFIG_TCG_NSC is not set
# CONFIG_TCG_ATMEL is not set
# CONFIG_TCG_INFINEON is not set
CONFIG_TCG_CRB=y
# CONFIG_TCG_VTPM_PROXY is not set
# CONFIG_TCG_TIS_ST33ZP24_I2C is not set
# CONFIG_TCG_TIS_ST33ZP24_SPI is not set
# CONFIG_TELCLOCK is not set
CONFIG_XILLYBUS_CLASS=y
# CONFIG_XILLYBUS is not set
CONFIG_XILLYUSB=y
# end of Character devices

#
# I2C support
#
CONFIG_I2C=y
CONFIG_ACPI_I2C_OPREGION=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y

#
# Multiplexer I2C Chip support
#
# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
# CONFIG_I2C_MUX_GPIO is not set
# CONFIG_I2C_MUX_GPMUX is not set
# CONFIG_I2C_MUX_LTC4306 is not set
# CONFIG_I2C_MUX_PCA9541 is not set
# CONFIG_I2C_MUX_PCA954x is not set
CONFIG_I2C_MUX_REG=y
# CONFIG_I2C_MUX_MLXCPLD is not set
# end of Multiplexer I2C Chip support

CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_SMBUS=y
CONFIG_I2C_ALGOBIT=y

#
# I2C Hardware Bus support
#

#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_AMD_MP2 is not set
CONFIG_I2C_I801=y
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_ISMT is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_CHT_WC is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_NVIDIA_GPU is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_ZHAOXIN is not set

#
# ACPI drivers
#
# CONFIG_I2C_SCMI is not set

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_CBUS_GPIO is not set
CONFIG_I2C_DESIGNWARE_CORE=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
# CONFIG_I2C_DESIGNWARE_BAYTRAIL is not set
# CONFIG_I2C_DESIGNWARE_PCI is not set
# CONFIG_I2C_EMEV2 is not set
# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_RK3X is not set
# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_XILINX is not set

#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_DIOLAN_U2C=y
CONFIG_I2C_DLN2=y
CONFIG_I2C_LJCA=y
CONFIG_I2C_CP2615=y
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PCI1XXXX is not set
CONFIG_I2C_ROBOTFUZZ_OSIF=y
# CONFIG_I2C_TAOS_EVM is not set
CONFIG_I2C_TINY_USB=y
CONFIG_I2C_VIPERBOARD=y

#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_MLXCPLD is not set
# CONFIG_I2C_VIRTIO is not set
# end of I2C Hardware Bus support

# CONFIG_I2C_STUB is not set
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=y
# CONFIG_I2C_SLAVE_TESTUNIT is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# end of I2C support

# CONFIG_I3C is not set
CONFIG_I3C_OR_I2C=y
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y
# CONFIG_SPI_MEM is not set

#
# SPI Master Controller Drivers
#
# CONFIG_SPI_ALTERA is not set
# CONFIG_SPI_AXI_SPI_ENGINE is not set
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_BUTTERFLY is not set
# CONFIG_SPI_CADENCE is not set
# CONFIG_SPI_CADENCE_QUADSPI is not set
# CONFIG_SPI_CH341 is not set
# CONFIG_SPI_DESIGNWARE is not set
CONFIG_SPI_DLN2=y
# CONFIG_SPI_GPIO is not set
# CONFIG_SPI_LM70_LLP is not set
# CONFIG_SPI_FSL_SPI is not set
CONFIG_SPI_LJCA=y
# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set
# CONFIG_SPI_MICROCHIP_CORE_SPI is not set
# CONFIG_SPI_LANTIQ_SSC is not set
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PCI1XXXX is not set
# CONFIG_SPI_PXA2XX is not set
# CONFIG_SPI_SC18IS602 is not set
# CONFIG_SPI_SIFIVE is not set
# CONFIG_SPI_MXIC is not set
# CONFIG_SPI_VIRTIO is not set
# CONFIG_SPI_XCOMM is not set
# CONFIG_SPI_XILINX is not set

#
# SPI Multiplexer support
#
# CONFIG_SPI_MUX is not set

#
# SPI Protocol Masters
#
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_LOOPBACK_TEST is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_SPI_SLAVE is not set
CONFIG_SPI_DYNAMIC=y
# CONFIG_SPMI is not set
# CONFIG_HSI is not set
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set

#
# PPS clients support
#
# CONFIG_PPS_CLIENT_KTIMER is not set
# CONFIG_PPS_CLIENT_LDISC is not set
# CONFIG_PPS_CLIENT_PARPORT is not set
# CONFIG_PPS_CLIENT_GPIO is not set
# CONFIG_PPS_GENERATOR is not set

#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y

#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
CONFIG_PTP_1588_CLOCK_KVM=y
CONFIG_PTP_1588_CLOCK_VMCLOCK=y
# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set
# CONFIG_PTP_1588_CLOCK_IDTCM is not set
# CONFIG_PTP_1588_CLOCK_FC3W is not set
# CONFIG_PTP_1588_CLOCK_MOCK is not set
# CONFIG_PTP_1588_CLOCK_VMW is not set
# CONFIG_PTP_1588_CLOCK_OCP is not set
# CONFIG_PTP_NETC_V4_TIMER is not set
# end of PTP clock support

#
# DPLL device support
#
# CONFIG_ZL3073X_I2C is not set
# CONFIG_ZL3073X_SPI is not set
# end of DPLL device support

# CONFIG_PINCTRL is not set
CONFIG_GPIOLIB_LEGACY=y
CONFIG_GPIOLIB=y
CONFIG_GPIOLIB_FASTPATH_LIMIT=512
CONFIG_OF_GPIO=y
CONFIG_GPIO_ACPI=y
CONFIG_GPIOLIB_IRQCHIP=y
# CONFIG_DEBUG_GPIO is not set
# CONFIG_GPIO_SYSFS is not set
# CONFIG_GPIO_CDEV is not set

#
# Memory mapped GPIO drivers
#
# CONFIG_GPIO_74XX_MMIO is not set
# CONFIG_GPIO_ALTERA is not set
# CONFIG_GPIO_AMDPT is not set
# CONFIG_GPIO_BY_PINCTRL is not set
# CONFIG_GPIO_CADENCE is not set
# CONFIG_GPIO_DWAPB is not set
# CONFIG_GPIO_FTGPIO010 is not set
# CONFIG_GPIO_GENERIC_PLATFORM is not set
# CONFIG_GPIO_GRANITERAPIDS is not set
# CONFIG_GPIO_GRGPIO is not set
# CONFIG_GPIO_HLWD is not set
# CONFIG_GPIO_ICH is not set
# CONFIG_GPIO_LOGICVC is not set
# CONFIG_GPIO_MB86S7X is not set
# CONFIG_GPIO_POLARFIRE_SOC is not set
# CONFIG_GPIO_SIFIVE is not set
# CONFIG_GPIO_SYSCON is not set
# CONFIG_GPIO_WAVESHARE_DSI_TOUCH is not set
# CONFIG_GPIO_XILINX is not set
# CONFIG_GPIO_AMD_FCH is not set
# end of Memory mapped GPIO drivers

#
# Port-mapped I/O GPIO drivers
#
# CONFIG_GPIO_VX855 is not set
# CONFIG_GPIO_F7188X is not set
# CONFIG_GPIO_IT87 is not set
# CONFIG_GPIO_NOVALAKE is not set
# CONFIG_GPIO_SCH311X is not set
# CONFIG_GPIO_WINBOND is not set
# CONFIG_GPIO_WS16C48 is not set
# end of Port-mapped I/O GPIO drivers

#
# I2C GPIO expanders
#
# CONFIG_GPIO_ADNP is not set
# CONFIG_GPIO_FXL6408 is not set
# CONFIG_GPIO_DS4520 is not set
# CONFIG_GPIO_GW_PLD is not set
# CONFIG_GPIO_MAX7300 is not set
# CONFIG_GPIO_MAX732X is not set
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCA9570 is not set
# CONFIG_GPIO_PCF857X is not set
# CONFIG_GPIO_TPIC2810 is not set
# end of I2C GPIO expanders

#
# MFD GPIO expanders
#
CONFIG_GPIO_DLN2=y
CONFIG_GPIO_LJCA=y
# CONFIG_GPIO_TWL4030 is not set
# CONFIG_GPIO_WHISKEY_COVE is not set
# end of MFD GPIO expanders

#
# Auxiliary Bus GPIO drivers
#
# end of Auxiliary Bus GPIO drivers

#
# PCI GPIO expanders
#
# CONFIG_GPIO_AMD8111 is not set
# CONFIG_GPIO_BT8XX is not set
# CONFIG_GPIO_ML_IOH is not set
# CONFIG_GPIO_PCI_IDIO_16 is not set
# CONFIG_GPIO_PCIE_IDIO_24 is not set
# CONFIG_GPIO_RDC321X is not set
# CONFIG_GPIO_SODAVILLE is not set
# end of PCI GPIO expanders

#
# SPI GPIO expanders
#
# CONFIG_GPIO_74X164 is not set
# CONFIG_GPIO_MAX3191X is not set
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MC33880 is not set
# CONFIG_GPIO_PISOSR is not set
# CONFIG_GPIO_XRA1403 is not set
# end of SPI GPIO expanders

#
# USB GPIO expanders
#
CONFIG_GPIO_VIPERBOARD=y
# CONFIG_GPIO_MPSSE is not set
# end of USB GPIO expanders

#
# Virtual GPIO drivers
#
# CONFIG_GPIO_AGGREGATOR is not set
# CONFIG_GPIO_LATCH is not set
# CONFIG_GPIO_LINE_MUX is not set
# CONFIG_GPIO_MOCKUP is not set
# CONFIG_GPIO_VIRTIO is not set
# CONFIG_GPIO_SIM is not set
# end of Virtual GPIO drivers

#
# GPIO Debugging utilities
#
# CONFIG_GPIO_SLOPPY_LOGIC_ANALYZER is not set
# CONFIG_GPIO_VIRTUSER is not set
# end of GPIO Debugging utilities

# CONFIG_W1 is not set
# CONFIG_POWER_RESET is not set
# CONFIG_POWER_SEQUENCING is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_POWER_SUPPLY_HWMON=y
# CONFIG_GENERIC_ADC_BATTERY is not set
# CONFIG_IP5XXX_POWER is not set
# CONFIG_TEST_POWER is not set
# CONFIG_CHARGER_ADP5061 is not set
# CONFIG_BATTERY_CHAGALL is not set
# CONFIG_BATTERY_CW2015 is not set
# CONFIG_BATTERY_DS2780 is not set
# CONFIG_BATTERY_DS2781 is not set
# CONFIG_BATTERY_DS2782 is not set
# CONFIG_BATTERY_SAMSUNG_SDI is not set
# CONFIG_BATTERY_S2MU005 is not set
# CONFIG_BATTERY_SBS is not set
# CONFIG_CHARGER_SBS is not set
# CONFIG_MANAGER_SBS is not set
# CONFIG_BATTERY_BQ27XXX is not set
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_BATTERY_MAX17042 is not set
# CONFIG_BATTERY_MAX1720X is not set
CONFIG_CHARGER_ISP1704=y
# CONFIG_CHARGER_MAX8903 is not set
# CONFIG_CHARGER_TWL4030 is not set
# CONFIG_CHARGER_TWL6030 is not set
# CONFIG_CHARGER_LP8727 is not set
# CONFIG_CHARGER_GPIO is not set
# CONFIG_CHARGER_MANAGER is not set
# CONFIG_CHARGER_LT3651 is not set
# CONFIG_CHARGER_LTC4162L is not set
# CONFIG_CHARGER_DETECTOR_MAX14656 is not set
# CONFIG_CHARGER_MAX77976 is not set
# CONFIG_CHARGER_MAX8971 is not set
# CONFIG_CHARGER_MT6360 is not set
# CONFIG_CHARGER_MT6370 is not set
# CONFIG_CHARGER_BQ2415X is not set
CONFIG_CHARGER_BQ24190=y
# CONFIG_CHARGER_BQ24257 is not set
# CONFIG_CHARGER_BQ24735 is not set
# CONFIG_CHARGER_BQ2515X is not set
# CONFIG_CHARGER_BQ25890 is not set
# CONFIG_CHARGER_BQ25980 is not set
# CONFIG_CHARGER_BQ256XX is not set
# CONFIG_CHARGER_SMB347 is not set
# CONFIG_BATTERY_GAUGE_LTC2941 is not set
# CONFIG_BATTERY_GOLDFISH is not set
# CONFIG_BATTERY_RT5033 is not set
# CONFIG_CHARGER_RT9455 is not set
# CONFIG_CHARGER_RT9467 is not set
# CONFIG_CHARGER_RT9471 is not set
# CONFIG_CHARGER_RT9756 is not set
# CONFIG_FUEL_GAUGE_STC3117 is not set
# CONFIG_CHARGER_UCS1002 is not set
# CONFIG_CHARGER_BD99954 is not set
# CONFIG_BATTERY_SURFACE is not set
# CONFIG_CHARGER_SURFACE is not set
# CONFIG_BATTERY_UG3105 is not set
# CONFIG_BATTERY_CHARGER_SURFACE_RT is not set
# CONFIG_FUEL_GAUGE_MM8013 is not set
CONFIG_HWMON=y
# CONFIG_HWMON_DEBUG_CHIP is not set

#
# Native drivers
#
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_ABITUGURU3 is not set
# CONFIG_SENSORS_AD7314 is not set
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM1177 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ADT7310 is not set
# CONFIG_SENSORS_ADT7410 is not set
# CONFIG_SENSORS_ADT7411 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_AHT10 is not set
CONFIG_SENSORS_AQUACOMPUTER_D5NEXT=y
# CONFIG_SENSORS_AS370 is not set
# CONFIG_SENSORS_ASC7621 is not set
# CONFIG_SENSORS_ASUS_ROG_RYUJIN is not set
# CONFIG_SENSORS_AXI_FAN_CONTROL is not set
# CONFIG_SENSORS_K8TEMP is not set
# CONFIG_SENSORS_K10TEMP is not set
# CONFIG_SENSORS_FAM15H_POWER is not set
# CONFIG_SENSORS_APPLESMC is not set
# CONFIG_SENSORS_ARCTIC_FAN_CONTROLLER is not set
# CONFIG_SENSORS_ASB100 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_CHIPCAP2 is not set
CONFIG_SENSORS_CORSAIR_CPRO=y
CONFIG_SENSORS_CORSAIR_PSU=y
# CONFIG_SENSORS_DRIVETEMP is not set
# CONFIG_SENSORS_DS620 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_DELL_SMM is not set
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
# CONFIG_SENSORS_FSCHMD is not set
# CONFIG_SENSORS_FTSTEUTATES is not set
CONFIG_SENSORS_GIGABYTE_WATERFORCE=y
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_GPD is not set
# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_G762 is not set
# CONFIG_SENSORS_GPIO_FAN is not set
# CONFIG_SENSORS_HIH6130 is not set
# CONFIG_SENSORS_HS3001 is not set
# CONFIG_SENSORS_HTU31 is not set
# CONFIG_SENSORS_IIO_HWMON is not set
# CONFIG_SENSORS_I5500 is not set
# CONFIG_SENSORS_CORETEMP is not set
# CONFIG_SENSORS_ISL28022 is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_JC42 is not set
CONFIG_SENSORS_POWERZ=y
# CONFIG_SENSORS_POWR1220 is not set
# CONFIG_SENSORS_PROM21_XHCI is not set
# CONFIG_SENSORS_LATTEPANDA_SIGMA_EC is not set
# CONFIG_SENSORS_LENOVO_EC is not set
# CONFIG_SENSORS_LINEAGE is not set
# CONFIG_SENSORS_LTC2945 is not set
# CONFIG_SENSORS_LTC2947_I2C is not set
# CONFIG_SENSORS_LTC2947_SPI is not set
# CONFIG_SENSORS_LTC2990 is not set
# CONFIG_SENSORS_LTC2991 is not set
# CONFIG_SENSORS_LTC2992 is not set
# CONFIG_SENSORS_LTC4151 is not set
# CONFIG_SENSORS_LTC4215 is not set
# CONFIG_SENSORS_LTC4222 is not set
# CONFIG_SENSORS_LTC4245 is not set
# CONFIG_SENSORS_LTC4260 is not set
# CONFIG_SENSORS_LTC4261 is not set
# CONFIG_SENSORS_LTC4282 is not set
# CONFIG_SENSORS_LTC4283 is not set
# CONFIG_SENSORS_MAX1111 is not set
# CONFIG_SENSORS_MAX127 is not set
# CONFIG_SENSORS_MAX16065 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX1668 is not set
# CONFIG_SENSORS_MAX197 is not set
# CONFIG_SENSORS_MAX31722 is not set
# CONFIG_SENSORS_MAX31730 is not set
# CONFIG_SENSORS_MAX31760 is not set
# CONFIG_MAX31827 is not set
# CONFIG_SENSORS_MAX6620 is not set
# CONFIG_SENSORS_MAX6621 is not set
# CONFIG_SENSORS_MAX6639 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_MAX6697 is not set
# CONFIG_SENSORS_MAX31790 is not set
# CONFIG_SENSORS_MC34VR500 is not set
# CONFIG_SENSORS_MCP3021 is not set
# CONFIG_SENSORS_MCP9982 is not set
# CONFIG_SENSORS_TC654 is not set
# CONFIG_SENSORS_TPS23861 is not set
# CONFIG_SENSORS_MR75203 is not set
# CONFIG_SENSORS_ADCXX is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM70 is not set
# CONFIG_SENSORS_LM73 is not set
# CONFIG_SENSORS_LM75 is not set
# CONFIG_SENSORS_LM77 is not set
# CONFIG_SENSORS_LM78 is not set
# CONFIG_SENSORS_LM80 is not set
# CONFIG_SENSORS_LM83 is not set
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
# CONFIG_SENSORS_LM95234 is not set
# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_LM95245 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_NTC_THERMISTOR is not set
# CONFIG_SENSORS_NCT6683 is not set
# CONFIG_SENSORS_NCT6775 is not set
# CONFIG_SENSORS_NCT6775_I2C is not set
# CONFIG_SENSORS_NCT7363 is not set
# CONFIG_SENSORS_NCT7802 is not set
# CONFIG_SENSORS_NCT7904 is not set
# CONFIG_SENSORS_NPCM7XX is not set
CONFIG_SENSORS_NZXT_KRAKEN2=y
# CONFIG_SENSORS_NZXT_KRAKEN3 is not set
CONFIG_SENSORS_NZXT_SMART2=y
# CONFIG_SENSORS_OCC_P8_I2C is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_PMBUS is not set
# CONFIG_SENSORS_PT5161L is not set
# CONFIG_SENSORS_SBTSI is not set
# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SHT21 is not set
# CONFIG_SENSORS_SHT3x is not set
# CONFIG_SENSORS_SHT4x is not set
# CONFIG_SENSORS_SHTC1 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_EMC1403 is not set
# CONFIG_SENSORS_EMC1812 is not set
# CONFIG_SENSORS_EMC2103 is not set
# CONFIG_SENSORS_EMC2305 is not set
# CONFIG_SENSORS_EMC6W201 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_SCH5627 is not set
# CONFIG_SENSORS_SCH5636 is not set
# CONFIG_SENSORS_STTS751 is not set
# CONFIG_SENSORS_SURFACE_FAN is not set
# CONFIG_SENSORS_SURFACE_TEMP is not set
# CONFIG_SENSORS_ADC128D818 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_ADS7871 is not set
# CONFIG_SENSORS_AMC6821 is not set
# CONFIG_SENSORS_INA209 is not set
# CONFIG_SENSORS_INA2XX is not set
# CONFIG_SENSORS_INA238 is not set
# CONFIG_SENSORS_INA3221 is not set
# CONFIG_SENSORS_SPD5118 is not set
# CONFIG_SENSORS_TC74 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_TMP102 is not set
# CONFIG_SENSORS_TMP103 is not set
# CONFIG_SENSORS_TMP108 is not set
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_TMP464 is not set
# CONFIG_SENSORS_TMP513 is not set
# CONFIG_SENSORS_TSC1641 is not set
# CONFIG_SENSORS_VIA_CPUTEMP is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83773G is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83795 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_XGENE is not set
# CONFIG_SENSORS_YOGAFAN is not set

#
# ACPI drivers
#
# CONFIG_SENSORS_ACPI_POWER is not set
# CONFIG_SENSORS_ATK0110 is not set
# CONFIG_SENSORS_ASUS_WMI is not set
# CONFIG_SENSORS_ASUS_EC is not set
# CONFIG_SENSORS_HP_WMI is not set
CONFIG_THERMAL=y
CONFIG_THERMAL_NETLINK=y
# CONFIG_THERMAL_STATISTICS is not set
# CONFIG_THERMAL_DEBUGFS is not set
# CONFIG_THERMAL_CORE_TESTING is not set
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_HWMON=y
# CONFIG_THERMAL_OF is not set
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
CONFIG_THERMAL_GOV_STEP_WISE=y
# CONFIG_THERMAL_GOV_BANG_BANG is not set
# CONFIG_THERMAL_GOV_USER_SPACE is not set
# CONFIG_PCIE_THERMAL is not set
# CONFIG_THERMAL_EMULATION is not set
# CONFIG_THERMAL_MMIO is not set

#
# Intel thermal drivers
#
# CONFIG_INTEL_POWERCLAMP is not set
CONFIG_X86_THERMAL_VECTOR=y
# CONFIG_X86_PKG_TEMP_THERMAL is not set
# CONFIG_INTEL_SOC_DTS_THERMAL is not set

#
# ACPI INT340X thermal drivers
#
# CONFIG_INT340X_THERMAL is not set
# end of ACPI INT340X thermal drivers

# CONFIG_INTEL_BXT_PMIC_THERMAL is not set
# CONFIG_INTEL_PCH_THERMAL is not set
# CONFIG_INTEL_TCC_COOLING is not set
# CONFIG_INTEL_HFI_THERMAL is not set
# end of Intel thermal drivers

# CONFIG_GENERIC_ADC_THERMAL is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_CORE is not set
# CONFIG_WATCHDOG_NOWAYOUT is not set
CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
CONFIG_WATCHDOG_OPEN_TIMEOUT=0
# CONFIG_WATCHDOG_SYSFS is not set
# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set

#
# Watchdog Pretimeout Governors
#

#
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
# CONFIG_GPIO_WATCHDOG is not set
# CONFIG_LENOVO_SE10_WDT is not set
# CONFIG_LENOVO_SE30_WDT is not set
# CONFIG_WDAT_WDT is not set
# CONFIG_XILINX_WATCHDOG is not set
# CONFIG_ZIIRAVE_WATCHDOG is not set
# CONFIG_CADENCE_WATCHDOG is not set
# CONFIG_DW_WATCHDOG is not set
# CONFIG_TWL4030_WATCHDOG is not set
# CONFIG_MAX63XX_WATCHDOG is not set
# CONFIG_RETU_WATCHDOG is not set
# CONFIG_ACQUIRE_WDT is not set
# CONFIG_ADVANTECH_WDT is not set
# CONFIG_ADVANTECH_EC_WDT is not set
# CONFIG_ALIM1535_WDT is not set
# CONFIG_ALIM7101_WDT is not set
# CONFIG_EBC_C384_WDT is not set
# CONFIG_EXAR_WDT is not set
# CONFIG_F71808E_WDT is not set
# CONFIG_SP5100_TCO is not set
# CONFIG_SBC_FITPC2_WATCHDOG is not set
# CONFIG_EUROTECH_WDT is not set
# CONFIG_IB700_WDT is not set
# CONFIG_IBMASR is not set
# CONFIG_WAFER_WDT is not set
# CONFIG_I6300ESB_WDT is not set
# CONFIG_IE6XX_WDT is not set
# CONFIG_INTEL_OC_WATCHDOG is not set
# CONFIG_ITCO_WDT is not set
# CONFIG_IT8712F_WDT is not set
# CONFIG_IT87_WDT is not set
# CONFIG_HP_WATCHDOG is not set
# CONFIG_SC1200_WDT is not set
# CONFIG_PC87413_WDT is not set
# CONFIG_NV_TCO is not set
# CONFIG_60XX_WDT is not set
# CONFIG_SMSC_SCH311X_WDT is not set
# CONFIG_SMSC37B787_WDT is not set
# CONFIG_TQMX86_WDT is not set
# CONFIG_VIA_WDT is not set
# CONFIG_W83627HF_WDT is not set
# CONFIG_W83877F_WDT is not set
# CONFIG_W83977F_WDT is not set
# CONFIG_SBC_EPX_C3_WATCHDOG is not set
# CONFIG_INTEL_MEI_WDT is not set
# CONFIG_NI903X_WDT is not set
# CONFIG_NIC7018_WDT is not set
# CONFIG_MEN_A21_WDT is not set

#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set

#
# USB-based Watchdog Cards
#
CONFIG_USBPCWATCHDOG=y
CONFIG_SSB_POSSIBLE=y
CONFIG_SSB=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
# CONFIG_SSB_PCIHOST is not set
CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
# CONFIG_SSB_PCMCIAHOST is not set
CONFIG_SSB_SDIOHOST_POSSIBLE=y
# CONFIG_SSB_SDIOHOST is not set
# CONFIG_SSB_DRIVER_GPIO is not set
CONFIG_BCMA_POSSIBLE=y
CONFIG_BCMA=y
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
# CONFIG_BCMA_HOST_PCI is not set
# CONFIG_BCMA_HOST_SOC is not set
# CONFIG_BCMA_DRIVER_PCI is not set
# CONFIG_BCMA_DRIVER_GMAC_CMN is not set
# CONFIG_BCMA_DRIVER_GPIO is not set
# CONFIG_BCMA_DEBUG is not set

#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
# CONFIG_MFD_ADP5585 is not set
# CONFIG_MFD_ACT8945A is not set
# CONFIG_MFD_AS3711 is not set
# CONFIG_MFD_SMPRO is not set
# CONFIG_MFD_AS3722 is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_AAT2870_CORE is not set
# CONFIG_MFD_ATMEL_FLEXCOM is not set
# CONFIG_MFD_ATMEL_HLCDC is not set
# CONFIG_MFD_BCM590XX is not set
# CONFIG_MFD_BD9571MWV is not set
# CONFIG_MFD_AXP20X_I2C is not set
# CONFIG_MFD_CGBC is not set
# CONFIG_MFD_CS40L50_I2C is not set
# CONFIG_MFD_CS40L50_SPI is not set
# CONFIG_MFD_CS42L43_I2C is not set
# CONFIG_MFD_CS42L43_SDW is not set
# CONFIG_MFD_LOCHNAGAR is not set
# CONFIG_MFD_MADERA is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_DA9052_SPI is not set
# CONFIG_MFD_DA9052_I2C is not set
# CONFIG_MFD_DA9055 is not set
# CONFIG_MFD_DA9062 is not set
# CONFIG_MFD_DA9063 is not set
# CONFIG_MFD_DA9150 is not set
CONFIG_MFD_DLN2=y
# CONFIG_MFD_GATEWORKS_GSC is not set
# CONFIG_MFD_MC13XXX_SPI is not set
# CONFIG_MFD_MC13XXX_I2C is not set
# CONFIG_MFD_MP2629 is not set
# CONFIG_MFD_PF1550 is not set
# CONFIG_MFD_HI6421_PMIC is not set
# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set
CONFIG_LPC_ICH=y
# CONFIG_LPC_SCH is not set
# CONFIG_INTEL_SOC_PMIC is not set
CONFIG_INTEL_SOC_PMIC_BXTWC=y
CONFIG_INTEL_SOC_PMIC_CHTWC=y
# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set
# CONFIG_MFD_INTEL_LPSS_ACPI is not set
# CONFIG_MFD_INTEL_LPSS_PCI is not set
CONFIG_MFD_INTEL_PMC_BXT=y
# CONFIG_MFD_IQS62X is not set
# CONFIG_MFD_JANZ_CMODIO is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_88PM800 is not set
# CONFIG_MFD_88PM805 is not set
# CONFIG_MFD_88PM860X is not set
# CONFIG_MFD_88PM886_PMIC is not set
# CONFIG_MFD_MAX5970 is not set
# CONFIG_MFD_MAX14577 is not set
# CONFIG_MFD_MAX77541 is not set
# CONFIG_MFD_MAX77620 is not set
# CONFIG_MFD_MAX77650 is not set
# CONFIG_MFD_MAX77686 is not set
# CONFIG_MFD_MAX77693 is not set
# CONFIG_MFD_MAX77705 is not set
# CONFIG_MFD_MAX77714 is not set
# CONFIG_MFD_MAX77759 is not set
# CONFIG_MFD_MAX77843 is not set
# CONFIG_MFD_MAX8907 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
# CONFIG_MFD_MAX8998 is not set
CONFIG_MFD_MT6360=y
CONFIG_MFD_MT6370=y
# CONFIG_MFD_MT6397 is not set
# CONFIG_MFD_MENF21BMC is not set
# CONFIG_MFD_NCT6694 is not set
# CONFIG_MFD_OCELOT is not set
# CONFIG_MFD_CPCAP is not set
CONFIG_MFD_VIPERBOARD=y
# CONFIG_MFD_NTXEC is not set
CONFIG_MFD_RETU=y
# CONFIG_MFD_SY7636A is not set
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_RT4831 is not set
# CONFIG_MFD_RT5033 is not set
# CONFIG_MFD_RT5120 is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_RK8XX_I2C is not set
# CONFIG_MFD_RK8XX_SPI is not set
# CONFIG_MFD_RN5T618 is not set
# CONFIG_MFD_SEC_I2C is not set
# CONFIG_MFD_SI476X_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_SKY81452 is not set
# CONFIG_MFD_STMPE is not set
CONFIG_MFD_SYSCON=y
# CONFIG_MFD_LP3943 is not set
# CONFIG_MFD_LP8788 is not set
# CONFIG_MFD_TI_LMU is not set
# CONFIG_MFD_BQ257XX is not set
# CONFIG_MFD_PALMAS is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
# CONFIG_TPS6507X is not set
# CONFIG_MFD_TPS65086 is not set
# CONFIG_MFD_TPS65090 is not set
# CONFIG_MFD_TPS65217 is not set
# CONFIG_MFD_TI_LP873X is not set
# CONFIG_MFD_TI_LP87565 is not set
# CONFIG_MFD_TPS65218 is not set
# CONFIG_MFD_TPS65219 is not set
# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_TPS65910 is not set
# CONFIG_MFD_TPS65912_I2C is not set
# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_MFD_TPS6594_I2C is not set
# CONFIG_MFD_TPS6594_SPI is not set
CONFIG_TWL4030_CORE=y
# CONFIG_MFD_TWL4030_AUDIO is not set
# CONFIG_TWL6040_CORE is not set
# CONFIG_MFD_LM3533 is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TQMX86 is not set
# CONFIG_MFD_VX855 is not set
# CONFIG_MFD_ARIZONA_I2C is not set
# CONFIG_MFD_ARIZONA_SPI is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_ROHM_BD718XX is not set
# CONFIG_MFD_ROHM_BD71828 is not set
# CONFIG_MFD_ROHM_BD957XMUF is not set
# CONFIG_MFD_ROHM_BD96801 is not set
# CONFIG_MFD_STPMIC1 is not set
# CONFIG_MFD_STMFX is not set
# CONFIG_MFD_ATC260X_I2C is not set
# CONFIG_MFD_QCOM_PM8008 is not set
# CONFIG_RAVE_SP_CORE is not set
# CONFIG_MFD_INTEL_M10_BMC_SPI is not set
# CONFIG_MFD_QNAP_MCU is not set
# CONFIG_MFD_RSMU_I2C is not set
# CONFIG_MFD_RSMU_SPI is not set
# CONFIG_MFD_UPBOARD_FPGA is not set
# CONFIG_MFD_MAX7360 is not set
# end of Multifunction device drivers

CONFIG_REGULATOR=y
# CONFIG_REGULATOR_DEBUG is not set
CONFIG_REGULATOR_FIXED_VOLTAGE=y
# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
# CONFIG_REGULATOR_NETLINK_EVENTS is not set
# CONFIG_REGULATOR_88PG86X is not set
# CONFIG_REGULATOR_ACT8865 is not set
# CONFIG_REGULATOR_AD5398 is not set
# CONFIG_REGULATOR_ADP5055 is not set
# CONFIG_REGULATOR_AW37503 is not set
# CONFIG_REGULATOR_DA9121 is not set
# CONFIG_REGULATOR_DA9210 is not set
# CONFIG_REGULATOR_DA9211 is not set
# CONFIG_REGULATOR_FAN53555 is not set
# CONFIG_REGULATOR_FAN53880 is not set
# CONFIG_REGULATOR_GPIO is not set
# CONFIG_REGULATOR_ISL9305 is not set
# CONFIG_REGULATOR_ISL6271A is not set
# CONFIG_REGULATOR_FP9931 is not set
# CONFIG_REGULATOR_LP3971 is not set
# CONFIG_REGULATOR_LP3972 is not set
# CONFIG_REGULATOR_LP872X is not set
# CONFIG_REGULATOR_LP8755 is not set
# CONFIG_REGULATOR_LTC3589 is not set
# CONFIG_REGULATOR_LTC3676 is not set
# CONFIG_REGULATOR_MAX1586 is not set
# CONFIG_REGULATOR_MAX77503 is not set
# CONFIG_REGULATOR_MAX77675 is not set
# CONFIG_REGULATOR_MAX77857 is not set
# CONFIG_REGULATOR_MAX8649 is not set
# CONFIG_REGULATOR_MAX8660 is not set
# CONFIG_REGULATOR_MAX8893 is not set
# CONFIG_REGULATOR_MAX8952 is not set
# CONFIG_REGULATOR_MAX20086 is not set
# CONFIG_REGULATOR_MAX20411 is not set
# CONFIG_REGULATOR_MAX77826 is not set
# CONFIG_REGULATOR_MAX77838 is not set
# CONFIG_REGULATOR_MCP16502 is not set
# CONFIG_REGULATOR_MP5416 is not set
# CONFIG_REGULATOR_MP8859 is not set
# CONFIG_REGULATOR_MP886X is not set
# CONFIG_REGULATOR_MPQ7920 is not set
# CONFIG_REGULATOR_MT6311 is not set
# CONFIG_REGULATOR_MT6360 is not set
# CONFIG_REGULATOR_MT6370 is not set
# CONFIG_REGULATOR_PCA9450 is not set
# CONFIG_REGULATOR_PF9453 is not set
# CONFIG_REGULATOR_PF0900 is not set
# CONFIG_REGULATOR_PF530X is not set
# CONFIG_REGULATOR_PF8X00 is not set
# CONFIG_REGULATOR_PFUZE100 is not set
# CONFIG_REGULATOR_PV88060 is not set
# CONFIG_REGULATOR_PV88080 is not set
# CONFIG_REGULATOR_PV88090 is not set
# CONFIG_REGULATOR_RAA215300 is not set
# CONFIG_REGULATOR_RT4801 is not set
# CONFIG_REGULATOR_RT4803 is not set
# CONFIG_REGULATOR_RT5133 is not set
# CONFIG_REGULATOR_RT5190A is not set
# CONFIG_REGULATOR_RT5739 is not set
# CONFIG_REGULATOR_RT5759 is not set
# CONFIG_REGULATOR_RT6160 is not set
# CONFIG_REGULATOR_RT6190 is not set
# CONFIG_REGULATOR_RT6245 is not set
# CONFIG_REGULATOR_RT8092 is not set
# CONFIG_REGULATOR_RTQ2134 is not set
# CONFIG_REGULATOR_RTMV20 is not set
# CONFIG_REGULATOR_RTQ6752 is not set
# CONFIG_REGULATOR_RTQ2208 is not set
# CONFIG_REGULATOR_SGM3804 is not set
# CONFIG_REGULATOR_SLG51000 is not set
# CONFIG_REGULATOR_SY8106A is not set
# CONFIG_REGULATOR_SY8824X is not set
# CONFIG_REGULATOR_SY8827N is not set
# CONFIG_REGULATOR_TPS51632 is not set
# CONFIG_REGULATOR_TPS62360 is not set
# CONFIG_REGULATOR_TPS6286X is not set
# CONFIG_REGULATOR_TPS6287X is not set
# CONFIG_REGULATOR_TPS65023 is not set
# CONFIG_REGULATOR_TPS6507X is not set
# CONFIG_REGULATOR_TPS65132 is not set
# CONFIG_REGULATOR_TPS65185 is not set
# CONFIG_REGULATOR_TPS6524X is not set
CONFIG_REGULATOR_TWL4030=y
# CONFIG_REGULATOR_VCTRL is not set
CONFIG_RC_CORE=y
# CONFIG_LIRC is not set
# CONFIG_RC_MAP is not set
# CONFIG_RC_DECODERS is not set
CONFIG_RC_DEVICES=y
# CONFIG_IR_ENE is not set
# CONFIG_IR_FINTEK is not set
# CONFIG_IR_GPIO_CIR is not set
# CONFIG_IR_HIX5HD2 is not set
CONFIG_IR_IGORPLUGUSB=y
CONFIG_IR_IGUANA=y
CONFIG_IR_IMON=y
CONFIG_IR_IMON_RAW=y
# CONFIG_IR_ITE_CIR is not set
CONFIG_IR_MCEUSB=y
# CONFIG_IR_NUVOTON is not set
CONFIG_IR_REDRAT3=y
# CONFIG_IR_SERIAL is not set
CONFIG_IR_STREAMZAP=y
CONFIG_IR_TOY=y
CONFIG_IR_TTUSBIR=y
# CONFIG_IR_WINBOND_CIR is not set
CONFIG_RC_ATI_REMOTE=y
# CONFIG_RC_LOOPBACK is not set
CONFIG_RC_XBOX_DVD=y
CONFIG_CEC_CORE=y

#
# CEC support
#
# CONFIG_MEDIA_CEC_RC is not set
CONFIG_MEDIA_CEC_SUPPORT=y
# CONFIG_CEC_CH7322 is not set
# CONFIG_CEC_NXP_TDA9950 is not set
# CONFIG_CEC_GPIO is not set
# CONFIG_CEC_SECO is not set
# CONFIG_USB_EXTRON_DA_HD_4K_PLUS_CEC is not set
CONFIG_USB_PULSE8_CEC=y
CONFIG_USB_RAINSHADOW_CEC=y
# end of CEC support

CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_SUPPORT_FILTER=y
# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set

#
# Media device types
#
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
CONFIG_MEDIA_RADIO_SUPPORT=y
CONFIG_MEDIA_SDR_SUPPORT=y
CONFIG_MEDIA_PLATFORM_SUPPORT=y
CONFIG_MEDIA_TEST_SUPPORT=y
# end of Media device types

CONFIG_VIDEO_DEV=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_DVB_CORE=y

#
# Video4Linux options
#
CONFIG_VIDEO_V4L2_I2C=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
# CONFIG_VIDEO_ADV_DEBUG is not set
# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
CONFIG_VIDEO_TUNER=y
CONFIG_V4L2_MEM2MEM_DEV=y
# end of Video4Linux options

#
# Media controller options
#
CONFIG_MEDIA_CONTROLLER_DVB=y
# end of Media controller options

#
# Digital TV options
#
# CONFIG_DVB_MMAP is not set
# CONFIG_DVB_NET is not set
CONFIG_DVB_MAX_ADAPTERS=16
# CONFIG_DVB_DYNAMIC_MINORS is not set
# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set
# CONFIG_DVB_ULE_DEBUG is not set
# end of Digital TV options

#
# Media drivers
#

#
# Drivers filtered as selected at 'Filter media drivers'
#

#
# Media drivers
#
CONFIG_MEDIA_USB_SUPPORT=y

#
# Webcam devices
#
CONFIG_USB_GSPCA=y
CONFIG_USB_GSPCA_BENQ=y
CONFIG_USB_GSPCA_CONEX=y
CONFIG_USB_GSPCA_CPIA1=y
CONFIG_USB_GSPCA_DTCS033=y
CONFIG_USB_GSPCA_ETOMS=y
CONFIG_USB_GSPCA_FINEPIX=y
CONFIG_USB_GSPCA_JEILINJ=y
CONFIG_USB_GSPCA_JL2005BCD=y
CONFIG_USB_GSPCA_KINECT=y
CONFIG_USB_GSPCA_KONICA=y
CONFIG_USB_GSPCA_MARS=y
CONFIG_USB_GSPCA_MR97310A=y
CONFIG_USB_GSPCA_NW80X=y
CONFIG_USB_GSPCA_OV519=y
CONFIG_USB_GSPCA_OV534=y
CONFIG_USB_GSPCA_OV534_9=y
CONFIG_USB_GSPCA_PAC207=y
CONFIG_USB_GSPCA_PAC7302=y
CONFIG_USB_GSPCA_PAC7311=y
CONFIG_USB_GSPCA_SE401=y
CONFIG_USB_GSPCA_SN9C2028=y
CONFIG_USB_GSPCA_SN9C20X=y
CONFIG_USB_GSPCA_SONIXB=y
CONFIG_USB_GSPCA_SONIXJ=y
CONFIG_USB_GSPCA_SPCA1528=y
CONFIG_USB_GSPCA_SPCA500=y
CONFIG_USB_GSPCA_SPCA501=y
CONFIG_USB_GSPCA_SPCA505=y
CONFIG_USB_GSPCA_SPCA506=y
CONFIG_USB_GSPCA_SPCA508=y
CONFIG_USB_GSPCA_SPCA561=y
CONFIG_USB_GSPCA_SQ905=y
CONFIG_USB_GSPCA_SQ905C=y
CONFIG_USB_GSPCA_SQ930X=y
CONFIG_USB_GSPCA_STK014=y
CONFIG_USB_GSPCA_STK1135=y
CONFIG_USB_GSPCA_STV0680=y
CONFIG_USB_GSPCA_SUNPLUS=y
CONFIG_USB_GSPCA_T613=y
CONFIG_USB_GSPCA_TOPRO=y
CONFIG_USB_GSPCA_TOUPTEK=y
CONFIG_USB_GSPCA_TV8532=y
CONFIG_USB_GSPCA_VC032X=y
CONFIG_USB_GSPCA_VICAM=y
CONFIG_USB_GSPCA_XIRLINK_CIT=y
CONFIG_USB_GSPCA_ZC3XX=y
CONFIG_USB_GL860=y
CONFIG_USB_M5602=y
CONFIG_USB_STV06XX=y
CONFIG_USB_PWC=y
# CONFIG_USB_PWC_DEBUG is not set
CONFIG_USB_PWC_INPUT_EVDEV=y
CONFIG_USB_S2255=y
CONFIG_VIDEO_USBTV=y
CONFIG_USB_VIDEO_CLASS=y
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y

#
# Analog TV USB devices
#
CONFIG_VIDEO_GO7007=y
CONFIG_VIDEO_GO7007_USB=y
CONFIG_VIDEO_GO7007_LOADER=y
CONFIG_VIDEO_GO7007_USB_S2250_BOARD=y
CONFIG_VIDEO_HDPVR=y
CONFIG_VIDEO_PVRUSB2=y
CONFIG_VIDEO_PVRUSB2_SYSFS=y
CONFIG_VIDEO_PVRUSB2_DVB=y
# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
CONFIG_VIDEO_STK1160=y

#
# Analog/digital TV USB devices
#
CONFIG_VIDEO_AU0828=y
CONFIG_VIDEO_AU0828_V4L2=y
CONFIG_VIDEO_AU0828_RC=y
CONFIG_VIDEO_CX231XX=y
CONFIG_VIDEO_CX231XX_RC=y
CONFIG_VIDEO_CX231XX_ALSA=y
CONFIG_VIDEO_CX231XX_DVB=y

#
# Digital TV USB devices
#
CONFIG_DVB_AS102=y
CONFIG_DVB_B2C2_FLEXCOP_USB=y
# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set
CONFIG_DVB_USB_V2=y
CONFIG_DVB_USB_AF9015=y
CONFIG_DVB_USB_AF9035=y
CONFIG_DVB_USB_ANYSEE=y
CONFIG_DVB_USB_AU6610=y
CONFIG_DVB_USB_AZ6007=y
CONFIG_DVB_USB_CE6230=y
CONFIG_DVB_USB_DVBSKY=y
CONFIG_DVB_USB_EC168=y
CONFIG_DVB_USB_GL861=y
CONFIG_DVB_USB_LME2510=y
CONFIG_DVB_USB_MXL111SF=y
CONFIG_DVB_USB_RTL28XXU=y
CONFIG_DVB_USB_ZD1301=y
CONFIG_DVB_USB=y
# CONFIG_DVB_USB_DEBUG is not set
CONFIG_DVB_USB_A800=y
CONFIG_DVB_USB_AF9005=y
CONFIG_DVB_USB_AF9005_REMOTE=y
CONFIG_DVB_USB_AZ6027=y
CONFIG_DVB_USB_CINERGY_T2=y
CONFIG_DVB_USB_CXUSB=y
CONFIG_DVB_USB_CXUSB_ANALOG=y
CONFIG_DVB_USB_DIB0700=y
CONFIG_DVB_USB_DIB3000MC=y
CONFIG_DVB_USB_DIBUSB_MB=y
# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
CONFIG_DVB_USB_DIBUSB_MC=y
CONFIG_DVB_USB_DIGITV=y
CONFIG_DVB_USB_DTT200U=y
CONFIG_DVB_USB_DTV5100=y
CONFIG_DVB_USB_DW2102=y
CONFIG_DVB_USB_GP8PSK=y
CONFIG_DVB_USB_M920X=y
CONFIG_DVB_USB_NOVA_T_USB2=y
CONFIG_DVB_USB_OPERA1=y
CONFIG_DVB_USB_PCTV452E=y
CONFIG_DVB_USB_TECHNISAT_USB2=y
CONFIG_DVB_USB_TTUSB2=y
CONFIG_DVB_USB_UMT_010=y
CONFIG_DVB_USB_VP702X=y
CONFIG_DVB_USB_VP7045=y
CONFIG_SMS_USB_DRV=y
CONFIG_DVB_TTUSB_BUDGET=y
CONFIG_DVB_TTUSB_DEC=y

#
# Webcam, TV (analog/digital) USB devices
#
CONFIG_VIDEO_EM28XX=y
CONFIG_VIDEO_EM28XX_V4L2=y
CONFIG_VIDEO_EM28XX_ALSA=y
CONFIG_VIDEO_EM28XX_DVB=y
CONFIG_VIDEO_EM28XX_RC=y

#
# Software defined radio USB devices
#
CONFIG_USB_AIRSPY=y
CONFIG_USB_HACKRF=y
CONFIG_USB_MSI2500=y
# CONFIG_MEDIA_PCI_SUPPORT is not set
CONFIG_RADIO_ADAPTERS=y
# CONFIG_RADIO_MAXIRADIO is not set
# CONFIG_RADIO_SAA7706H is not set
CONFIG_RADIO_SHARK=y
CONFIG_RADIO_SHARK2=y
CONFIG_RADIO_SI4713=y
CONFIG_RADIO_TEA575X=y
# CONFIG_RADIO_TEA5764 is not set
# CONFIG_RADIO_TEF6862 is not set
CONFIG_USB_DSBR=y
CONFIG_USB_KEENE=y
CONFIG_USB_MA901=y
CONFIG_USB_MR800=y
CONFIG_USB_RAREMONO=y
CONFIG_RADIO_SI470X=y
CONFIG_USB_SI470X=y
# CONFIG_I2C_SI470X is not set
CONFIG_USB_SI4713=y
# CONFIG_PLATFORM_SI4713 is not set
CONFIG_I2C_SI4713=y
# CONFIG_MEDIA_PLATFORM_DRIVERS is not set

#
# MMC/SDIO DVB adapters
#
CONFIG_SMS_SDIO_DRV=y
CONFIG_V4L_TEST_DRIVERS=y
CONFIG_VIDEO_VIM2M=y
CONFIG_VIDEO_VICODEC=y
CONFIG_VIDEO_VIMC=y
CONFIG_VIDEO_VIVID=y
CONFIG_VIDEO_VIVID_CEC=y
# CONFIG_VIDEO_VIVID_OSD is not set
CONFIG_VIDEO_VIVID_MAX_DEVS=64
# CONFIG_VIDEO_VISL is not set
CONFIG_DVB_TEST_DRIVERS=y
CONFIG_DVB_VIDTV=y

#
# FireWire (IEEE 1394) Adapters
#
# CONFIG_DVB_FIREDTV is not set
CONFIG_MEDIA_COMMON_OPTIONS=y

#
# common driver options
#
CONFIG_CYPRESS_FIRMWARE=y
CONFIG_TTPCI_EEPROM=y
CONFIG_UVC_COMMON=y
CONFIG_VIDEO_CX2341X=y
CONFIG_VIDEO_TVEEPROM=y
CONFIG_DVB_B2C2_FLEXCOP=y
CONFIG_SMS_SIANO_MDTV=y
CONFIG_SMS_SIANO_RC=y
CONFIG_SMS_SIANO_DEBUGFS=y
CONFIG_VIDEO_V4L2_TPG=y
CONFIG_VIDEOBUF2_CORE=y
CONFIG_VIDEOBUF2_V4L2=y
CONFIG_VIDEOBUF2_MEMOPS=y
CONFIG_VIDEOBUF2_DMA_CONTIG=y
CONFIG_VIDEOBUF2_VMALLOC=y
CONFIG_VIDEOBUF2_DMA_SG=y
# end of Media drivers

#
# Media ancillary drivers
#
CONFIG_MEDIA_ATTACH=y
# CONFIG_VIDEO_IR_I2C is not set
# CONFIG_VIDEO_CAMERA_SENSOR is not set

#
# Camera ISPs
#
# CONFIG_VIDEO_THP7312 is not set
# end of Camera ISPs

# CONFIG_VIDEO_CAMERA_LENS is not set

#
# Flash devices
#
# CONFIG_VIDEO_ADP1653 is not set
# CONFIG_VIDEO_LM3560 is not set
# CONFIG_VIDEO_LM3646 is not set
# end of Flash devices

#
# Audio decoders, processors and mixers
#
# CONFIG_VIDEO_CS3308 is not set
# CONFIG_VIDEO_CS5345 is not set
CONFIG_VIDEO_CS53L32A=y
CONFIG_VIDEO_MSP3400=y
# CONFIG_VIDEO_SONY_BTF_MPX is not set
# CONFIG_VIDEO_TDA1997X is not set
# CONFIG_VIDEO_TDA7432 is not set
# CONFIG_VIDEO_TDA9840 is not set
# CONFIG_VIDEO_TEA6415C is not set
# CONFIG_VIDEO_TEA6420 is not set
# CONFIG_VIDEO_TLV320AIC23B is not set
# CONFIG_VIDEO_TVAUDIO is not set
# CONFIG_VIDEO_UDA1342 is not set
# CONFIG_VIDEO_VP27SMPX is not set
# CONFIG_VIDEO_WM8739 is not set
CONFIG_VIDEO_WM8775=y
# end of Audio decoders, processors and mixers

#
# RDS decoders
#
# CONFIG_VIDEO_SAA6588 is not set
# end of RDS decoders

#
# Video decoders
#
# CONFIG_VIDEO_ADV7180 is not set
# CONFIG_VIDEO_ADV7183 is not set
# CONFIG_VIDEO_ADV748X is not set
# CONFIG_VIDEO_ADV7604 is not set
# CONFIG_VIDEO_ADV7842 is not set
# CONFIG_VIDEO_BT819 is not set
# CONFIG_VIDEO_BT856 is not set
# CONFIG_VIDEO_BT866 is not set
# CONFIG_VIDEO_ISL7998X is not set
# CONFIG_VIDEO_LT6911UXE is not set
# CONFIG_VIDEO_KS0127 is not set
# CONFIG_VIDEO_MAX9286 is not set
# CONFIG_VIDEO_ML86V7667 is not set
# CONFIG_VIDEO_SAA7110 is not set
CONFIG_VIDEO_SAA711X=y
# CONFIG_VIDEO_TC358743 is not set
# CONFIG_VIDEO_TC358746 is not set
# CONFIG_VIDEO_TVP514X is not set
# CONFIG_VIDEO_TVP5150 is not set
# CONFIG_VIDEO_TVP7002 is not set
# CONFIG_VIDEO_TW2804 is not set
# CONFIG_VIDEO_TW9900 is not set
# CONFIG_VIDEO_TW9903 is not set
# CONFIG_VIDEO_TW9906 is not set
# CONFIG_VIDEO_TW9910 is not set
# CONFIG_VIDEO_VPX3220 is not set

#
# Video and audio decoders
#
# CONFIG_VIDEO_SAA717X is not set
CONFIG_VIDEO_CX25840=y
# end of Video decoders

#
# Video encoders
#
# CONFIG_VIDEO_ADV7170 is not set
# CONFIG_VIDEO_ADV7175 is not set
# CONFIG_VIDEO_ADV7343 is not set
# CONFIG_VIDEO_ADV7393 is not set
# CONFIG_VIDEO_ADV7511 is not set
# CONFIG_VIDEO_AK881X is not set
# CONFIG_VIDEO_SAA7127 is not set
# CONFIG_VIDEO_SAA7185 is not set
# CONFIG_VIDEO_THS8200 is not set
# end of Video encoders

#
# Video improvement chips
#
# CONFIG_VIDEO_UPD64031A is not set
# CONFIG_VIDEO_UPD64083 is not set
# end of Video improvement chips

#
# Audio/Video compression chips
#
# CONFIG_VIDEO_SAA6752HS is not set
# end of Audio/Video compression chips

#
# SDR tuner chips
#
# CONFIG_SDR_MAX2175 is not set
# end of SDR tuner chips

#
# Miscellaneous helper chips
#
# CONFIG_VIDEO_INTEL_CVS is not set
# CONFIG_VIDEO_I2C is not set
# CONFIG_VIDEO_M52790 is not set
# CONFIG_VIDEO_ST_MIPID02 is not set
# CONFIG_VIDEO_THS7303 is not set
# end of Miscellaneous helper chips

#
# Video serializers and deserializers
#
# CONFIG_VIDEO_DS90UB913 is not set
# CONFIG_VIDEO_DS90UB953 is not set
# CONFIG_VIDEO_DS90UB960 is not set
# CONFIG_VIDEO_MAX96714 is not set
# CONFIG_VIDEO_MAX96717 is not set
# end of Video serializers and deserializers

#
# Media SPI Adapters
#
# CONFIG_CXD2880_SPI_DRV is not set
# CONFIG_VIDEO_GS1662 is not set
# end of Media SPI Adapters

CONFIG_MEDIA_TUNER=y

#
# Customize TV tuners
#
# CONFIG_MEDIA_TUNER_E4000 is not set
# CONFIG_MEDIA_TUNER_FC0011 is not set
# CONFIG_MEDIA_TUNER_FC0012 is not set
# CONFIG_MEDIA_TUNER_FC0013 is not set
# CONFIG_MEDIA_TUNER_FC2580 is not set
# CONFIG_MEDIA_TUNER_IT913X is not set
# CONFIG_MEDIA_TUNER_M88RS6000T is not set
# CONFIG_MEDIA_TUNER_MAX2165 is not set
# CONFIG_MEDIA_TUNER_MC44S803 is not set
CONFIG_MEDIA_TUNER_MSI001=y
# CONFIG_MEDIA_TUNER_MT2060 is not set
# CONFIG_MEDIA_TUNER_MT2063 is not set
# CONFIG_MEDIA_TUNER_MT20XX is not set
# CONFIG_MEDIA_TUNER_MT2131 is not set
# CONFIG_MEDIA_TUNER_MT2266 is not set
# CONFIG_MEDIA_TUNER_MXL301RF is not set
# CONFIG_MEDIA_TUNER_MXL5005S is not set
# CONFIG_MEDIA_TUNER_MXL5007T is not set
# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set
# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set
# CONFIG_MEDIA_TUNER_QT1010 is not set
# CONFIG_MEDIA_TUNER_R820T is not set
# CONFIG_MEDIA_TUNER_SI2157 is not set
# CONFIG_MEDIA_TUNER_SIMPLE is not set
# CONFIG_MEDIA_TUNER_TDA18212 is not set
# CONFIG_MEDIA_TUNER_TDA18218 is not set
# CONFIG_MEDIA_TUNER_TDA18250 is not set
# CONFIG_MEDIA_TUNER_TDA18271 is not set
# CONFIG_MEDIA_TUNER_TDA827X is not set
# CONFIG_MEDIA_TUNER_TDA8290 is not set
# CONFIG_MEDIA_TUNER_TDA9887 is not set
# CONFIG_MEDIA_TUNER_TEA5761 is not set
# CONFIG_MEDIA_TUNER_TEA5767 is not set
# CONFIG_MEDIA_TUNER_TUA9001 is not set
# CONFIG_MEDIA_TUNER_XC2028 is not set
# CONFIG_MEDIA_TUNER_XC4000 is not set
# CONFIG_MEDIA_TUNER_XC5000 is not set
# end of Customize TV tuners

#
# Customise DVB Frontends
#

#
# Multistandard (satellite) frontends
#
# CONFIG_DVB_M88DS3103 is not set
# CONFIG_DVB_MXL5XX is not set
# CONFIG_DVB_STB0899 is not set
# CONFIG_DVB_STB6100 is not set
# CONFIG_DVB_STV090x is not set
# CONFIG_DVB_STV0910 is not set
# CONFIG_DVB_STV6110x is not set
# CONFIG_DVB_STV6111 is not set

#
# Multistandard (cable + terrestrial) frontends
#
# CONFIG_DVB_DRXK is not set
# CONFIG_DVB_MN88472 is not set
# CONFIG_DVB_MN88473 is not set
# CONFIG_DVB_SI2165 is not set
# CONFIG_DVB_TDA18271C2DD is not set

#
# DVB-S (satellite) frontends
#
# CONFIG_DVB_CX24110 is not set
# CONFIG_DVB_CX24116 is not set
# CONFIG_DVB_CX24117 is not set
# CONFIG_DVB_CX24120 is not set
# CONFIG_DVB_CX24123 is not set
# CONFIG_DVB_DS3000 is not set
# CONFIG_DVB_MB86A16 is not set
# CONFIG_DVB_MT312 is not set
# CONFIG_DVB_S5H1420 is not set
# CONFIG_DVB_SI21XX is not set
# CONFIG_DVB_STB6000 is not set
# CONFIG_DVB_STV0288 is not set
# CONFIG_DVB_STV0299 is not set
# CONFIG_DVB_STV0900 is not set
# CONFIG_DVB_STV6110 is not set
# CONFIG_DVB_TDA10071 is not set
# CONFIG_DVB_TDA10086 is not set
# CONFIG_DVB_TDA8083 is not set
# CONFIG_DVB_TDA8261 is not set
# CONFIG_DVB_TDA826X is not set
# CONFIG_DVB_TS2020 is not set
# CONFIG_DVB_TUA6100 is not set
# CONFIG_DVB_TUNER_CX24113 is not set
# CONFIG_DVB_TUNER_ITD1000 is not set
# CONFIG_DVB_VES1X93 is not set
# CONFIG_DVB_ZL10036 is not set
# CONFIG_DVB_ZL10039 is not set

#
# DVB-T (terrestrial) frontends
#
CONFIG_DVB_AF9013=y
CONFIG_DVB_AS102_FE=y
# CONFIG_DVB_CX22700 is not set
# CONFIG_DVB_CX22702 is not set
# CONFIG_DVB_CXD2820R is not set
# CONFIG_DVB_CXD2841ER is not set
CONFIG_DVB_DIB3000MB=y
CONFIG_DVB_DIB3000MC=y
# CONFIG_DVB_DIB7000M is not set
# CONFIG_DVB_DIB7000P is not set
# CONFIG_DVB_DIB9000 is not set
# CONFIG_DVB_DRXD is not set
CONFIG_DVB_EC100=y
CONFIG_DVB_GP8PSK_FE=y
# CONFIG_DVB_L64781 is not set
# CONFIG_DVB_MT352 is not set
# CONFIG_DVB_NXT6000 is not set
CONFIG_DVB_RTL2830=y
CONFIG_DVB_RTL2832=y
CONFIG_DVB_RTL2832_SDR=y
# CONFIG_DVB_S5H1432 is not set
# CONFIG_DVB_SI2168 is not set
# CONFIG_DVB_SP887X is not set
# CONFIG_DVB_STV0367 is not set
# CONFIG_DVB_TDA10048 is not set
# CONFIG_DVB_TDA1004X is not set
# CONFIG_DVB_ZD1301_DEMOD is not set
CONFIG_DVB_ZL10353=y
# CONFIG_DVB_CXD2880 is not set

#
# DVB-C (cable) frontends
#
# CONFIG_DVB_STV0297 is not set
# CONFIG_DVB_TDA10021 is not set
# CONFIG_DVB_TDA10023 is not set
# CONFIG_DVB_VES1820 is not set

#
# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
#
# CONFIG_DVB_AU8522_DTV is not set
# CONFIG_DVB_AU8522_V4L is not set
# CONFIG_DVB_BCM3510 is not set
# CONFIG_DVB_LG2160 is not set
# CONFIG_DVB_LGDT3305 is not set
# CONFIG_DVB_LGDT3306A is not set
# CONFIG_DVB_LGDT330X is not set
# CONFIG_DVB_MXL692 is not set
# CONFIG_DVB_NXT200X is not set
# CONFIG_DVB_OR51132 is not set
# CONFIG_DVB_OR51211 is not set
# CONFIG_DVB_S5H1409 is not set
# CONFIG_DVB_S5H1411 is not set

#
# ISDB-T (terrestrial) frontends
#
# CONFIG_DVB_DIB8000 is not set
# CONFIG_DVB_MB86A20S is not set
# CONFIG_DVB_S921 is not set

#
# ISDB-S (satellite) & ISDB-T (terrestrial) frontends
#
# CONFIG_DVB_MN88443X is not set
# CONFIG_DVB_TC90522 is not set

#
# Digital terrestrial only tuners/PLL
#
# CONFIG_DVB_PLL is not set
# CONFIG_DVB_TUNER_DIB0070 is not set
# CONFIG_DVB_TUNER_DIB0090 is not set

#
# SEC control devices for DVB-S
#
# CONFIG_DVB_A8293 is not set
CONFIG_DVB_AF9033=y
# CONFIG_DVB_ASCOT2E is not set
# CONFIG_DVB_ATBM8830 is not set
# CONFIG_DVB_HELENE is not set
# CONFIG_DVB_HORUS3A is not set
# CONFIG_DVB_ISL6405 is not set
# CONFIG_DVB_ISL6421 is not set
# CONFIG_DVB_ISL6423 is not set
# CONFIG_DVB_IX2505V is not set
# CONFIG_DVB_LGS8GL5 is not set
# CONFIG_DVB_LGS8GXX is not set
# CONFIG_DVB_LNBH25 is not set
# CONFIG_DVB_LNBH29 is not set
# CONFIG_DVB_LNBP21 is not set
# CONFIG_DVB_LNBP22 is not set
# CONFIG_DVB_M88RS2000 is not set
# CONFIG_DVB_TDA665x is not set
# CONFIG_DVB_DRX39XYJ is not set

#
# Common Interface (EN50221) controller drivers
#
# CONFIG_DVB_CXD2099 is not set
# CONFIG_DVB_SP2 is not set
# end of Customise DVB Frontends

#
# Tools to develop new frontends
#
# CONFIG_DVB_DUMMY_FE is not set
# end of Media ancillary drivers

#
# Graphics support
#
CONFIG_APERTURE_HELPERS=y
CONFIG_SCREEN_INFO=y
CONFIG_VIDEO=y
# CONFIG_AUXDISPLAY is not set
# CONFIG_PANEL is not set
CONFIG_AGP=y
CONFIG_AGP_AMD64=y
CONFIG_AGP_INTEL=y
# CONFIG_AGP_SIS is not set
# CONFIG_AGP_VIA is not set
CONFIG_INTEL_GTT=y
# CONFIG_VGA_SWITCHEROO is not set
CONFIG_GPU_BUDDY=y
CONFIG_DRM=y

#
# DRM debugging options
#
# CONFIG_DRM_WERROR is not set
CONFIG_DRM_DEBUG_MM=y
# end of DRM debugging options

CONFIG_DRM_MIPI_DSI=y
CONFIG_DRM_KMS_HELPER=y
# CONFIG_DRM_PANIC is not set
# CONFIG_DRM_RAS is not set
# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set
# CONFIG_DRM_DEBUG_MODESET_LOCK is not set
CONFIG_DRM_CLIENT=y
CONFIG_DRM_CLIENT_LIB=y
CONFIG_DRM_CLIENT_SELECTION=y
CONFIG_DRM_CLIENT_SETUP=y

#
# Supported DRM clients
#
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100
# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set
# CONFIG_DRM_CLIENT_LOG is not set
CONFIG_DRM_CLIENT_DEFAULT_FBDEV=y
CONFIG_DRM_CLIENT_DEFAULT="fbdev"
# end of Supported DRM clients

# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
CONFIG_DRM_DISPLAY_DP_AUX_BUS=y
CONFIG_DRM_DISPLAY_HELPER=y
# CONFIG_DRM_DISPLAY_DP_AUX_CEC is not set
# CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV is not set
CONFIG_DRM_DISPLAY_DP_HELPER=y
CONFIG_DRM_DISPLAY_DSC_HELPER=y
CONFIG_DRM_DISPLAY_HDCP_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_HELPER=y
CONFIG_DRM_TTM=y
CONFIG_DRM_BUDDY=y
CONFIG_DRM_TTM_HELPER=y
CONFIG_DRM_GEM_SHMEM_HELPER=y
# CONFIG_DRM_AMDGPU is not set

#
# ARM devices
#
# CONFIG_DRM_KOMEDA is not set
# end of ARM devices

# CONFIG_DRM_AST is not set
CONFIG_DRM_BRIDGE=y
CONFIG_DRM_PANEL_BRIDGE=y
CONFIG_DRM_AUX_BRIDGE=y
CONFIG_DRM_AUX_HPD_BRIDGE=y

#
# Display Interface Bridges
#
# CONFIG_DRM_CHIPONE_ICN6211 is not set
# CONFIG_DRM_CHRONTEL_CH7033 is not set
# CONFIG_DRM_DISPLAY_CONNECTOR is not set
# CONFIG_DRM_I2C_NXP_TDA998X is not set
# CONFIG_DRM_ITE_IT6263 is not set
# CONFIG_DRM_ITE_IT6505 is not set
# CONFIG_DRM_LONTIUM_LT8912B is not set
# CONFIG_DRM_LONTIUM_LT9211 is not set
# CONFIG_DRM_LONTIUM_LT9611 is not set
# CONFIG_DRM_LONTIUM_LT9611UXC is not set
# CONFIG_DRM_LONTIUM_LT8713SX is not set
# CONFIG_DRM_ITE_IT66121 is not set
# CONFIG_DRM_LVDS_CODEC is not set
# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set
# CONFIG_DRM_NWL_MIPI_DSI is not set
# CONFIG_DRM_NXP_PTN3460 is not set
# CONFIG_DRM_PARADE_PS8622 is not set
# CONFIG_DRM_PARADE_PS8640 is not set
# CONFIG_DRM_SAMSUNG_DSIM is not set
# CONFIG_DRM_SIL_SII8620 is not set
# CONFIG_DRM_SII902X is not set
# CONFIG_DRM_SII9234 is not set
# CONFIG_DRM_SIMPLE_BRIDGE is not set
# CONFIG_DRM_SOLOMON_SSD2825 is not set
# CONFIG_DRM_THINE_THC63LVD1024 is not set
# CONFIG_DRM_TOSHIBA_TC358762 is not set
# CONFIG_DRM_TOSHIBA_TC358764 is not set
# CONFIG_DRM_TOSHIBA_TC358767 is not set
# CONFIG_DRM_TOSHIBA_TC358768 is not set
# CONFIG_DRM_TOSHIBA_TC358775 is not set
# CONFIG_DRM_TI_DLPC3433 is not set
# CONFIG_DRM_TI_TDP158 is not set
# CONFIG_DRM_TI_TFP410 is not set
# CONFIG_DRM_TI_SN65DSI83 is not set
# CONFIG_DRM_TI_SN65DSI86 is not set
# CONFIG_DRM_TI_TPD12S015 is not set
# CONFIG_DRM_WAVESHARE_BRIDGE is not set
# CONFIG_DRM_ANALOGIX_ANX6345 is not set
# CONFIG_DRM_ANALOGIX_ANX78XX is not set
# CONFIG_DRM_ANALOGIX_ANX7625 is not set
# CONFIG_DRM_I2C_ADV7511 is not set
# CONFIG_DRM_CDNS_DSI is not set
# CONFIG_DRM_CDNS_MHDP8546 is not set
# end of Display Interface Bridges

# CONFIG_DRM_ETNAVIV is not set
# CONFIG_DRM_GMA500 is not set
CONFIG_DRM_GUD=y
# CONFIG_DRM_HISI_HIBMC is not set
CONFIG_DRM_I915=y
CONFIG_DRM_I915_FORCE_PROBE=""
CONFIG_DRM_I915_CAPTURE_ERROR=y
CONFIG_DRM_I915_COMPRESS_ERROR=y
CONFIG_DRM_I915_USERPTR=y
# CONFIG_DRM_I915_GVT_KVMGT is not set
# CONFIG_DRM_I915_DP_TUNNEL is not set

#
# drm/i915 Debugging
#
# CONFIG_DRM_I915_WERROR is not set
# CONFIG_DRM_I915_REPLAY_GPU_HANGS_API is not set
# CONFIG_DRM_I915_DEBUG is not set
# CONFIG_DRM_I915_DEBUG_MMIO is not set
# CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS is not set
# CONFIG_DRM_I915_SW_FENCE_CHECK_DAG is not set
# CONFIG_DRM_I915_DEBUG_GUC is not set
# CONFIG_DRM_I915_SELFTEST is not set
# CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS is not set
# CONFIG_DRM_I915_DEBUG_VBLANK_EVADE is not set
# CONFIG_DRM_I915_DEBUG_RUNTIME_PM is not set
# CONFIG_DRM_I915_DEBUG_WAKEREF is not set
# end of drm/i915 Debugging

#
# drm/i915 Profile Guided Optimisation
#
CONFIG_DRM_I915_REQUEST_TIMEOUT=20000
CONFIG_DRM_I915_FENCE_TIMEOUT=10000
CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND=250
CONFIG_DRM_I915_HEARTBEAT_INTERVAL=2500
CONFIG_DRM_I915_PREEMPT_TIMEOUT=640
CONFIG_DRM_I915_PREEMPT_TIMEOUT_COMPUTE=7500
CONFIG_DRM_I915_MAX_REQUEST_BUSYWAIT=8000
CONFIG_DRM_I915_STOP_TIMEOUT=100
CONFIG_DRM_I915_TIMESLICE_DURATION=1
# end of drm/i915 Profile Guided Optimisation

# CONFIG_DRM_LOGICVC is not set
# CONFIG_DRM_MGAG200 is not set
# CONFIG_DRM_NOUVEAU is not set
CONFIG_DRM_PANEL=y

#
# Display Panels
#
# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set
# CONFIG_DRM_PANEL_ARM_VERSATILE is not set
# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set
# CONFIG_DRM_PANEL_AUO_A030JTN01 is not set
# CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set
# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set
# CONFIG_DRM_PANEL_BOE_TD4320 is not set
# CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A is not set
# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set
# CONFIG_DRM_PANEL_BOE_TV101WUM_LL2 is not set
# CONFIG_DRM_PANEL_CHIPWEALTH_CH13726A is not set
# CONFIG_DRM_PANEL_EBBG_FT8719 is not set
# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set
# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set
# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set
# CONFIG_DRM_PANEL_FOCALTECH_OTA7290B is not set
# CONFIG_DRM_PANEL_DSI_CM is not set
# CONFIG_DRM_PANEL_LVDS is not set
# CONFIG_DRM_PANEL_HIMAX_HX8279 is not set
# CONFIG_DRM_PANEL_HIMAX_HX83102 is not set
# CONFIG_DRM_PANEL_HIMAX_HX83112A is not set
# CONFIG_DRM_PANEL_HIMAX_HX83112B is not set
# CONFIG_DRM_PANEL_HIMAX_HX83121A is not set
# CONFIG_DRM_PANEL_HIMAX_HX8394 is not set
# CONFIG_DRM_PANEL_HYDIS_HV101HD1 is not set
# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9805 is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9806E_DSI is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9806E_SPI is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set
# CONFIG_DRM_PANEL_ILITEK_ILI9882T is not set
# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set
# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set
# CONFIG_DRM_PANEL_JADARD_JD9365DA_H3 is not set
# CONFIG_DRM_PANEL_JDI_LPM102A188A is not set
# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set
# CONFIG_DRM_PANEL_JDI_R63452 is not set
# CONFIG_DRM_PANEL_KHADAS_TS050 is not set
# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set
# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set
# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set
# CONFIG_DRM_PANEL_LINCOLNTECH_LCD197 is not set
# CONFIG_DRM_PANEL_LG_LB035Q02 is not set
# CONFIG_DRM_PANEL_LG_LD070WX3 is not set
# CONFIG_DRM_PANEL_LG_LG4573 is not set
# CONFIG_DRM_PANEL_LG_SW43408 is not set
# CONFIG_DRM_PANEL_LXD_M9189A is not set
# CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966 is not set
# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set
# CONFIG_DRM_PANEL_MOTOROLA_MOT is not set
# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
# CONFIG_DRM_PANEL_NEWVISION_NV3051D is not set
# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35532 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT36523 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set
# CONFIG_DRM_PANEL_NOVATEK_NT36672E is not set
# CONFIG_DRM_PANEL_NOVATEK_NT37700F is not set
# CONFIG_DRM_PANEL_NOVATEK_NT37801 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set
# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set
# CONFIG_DRM_PANEL_ORISETECH_OTA5601A is not set
# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set
# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set
# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set
# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set
# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set
# CONFIG_DRM_PANEL_RAYDIUM_RM67200 is not set
# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set
# CONFIG_DRM_PANEL_RAYDIUM_RM692E5 is not set
# CONFIG_DRM_PANEL_RAYDIUM_RM69380 is not set
# CONFIG_DRM_PANEL_RENESAS_R61307 is not set
# CONFIG_DRM_PANEL_RENESAS_R69328 is not set
# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set
# CONFIG_DRM_PANEL_SAMSUNG_AMS581VF01 is not set
# CONFIG_DRM_PANEL_SAMSUNG_AMS639RQ08 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS427AP24 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set
# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set
# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set
# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
# CONFIG_DRM_PANEL_SAMSUNG_LTL106HL02 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E3FA7 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E3FC2X01 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA8 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA5X01_AMS561RA01 is not set
# CONFIG_DRM_PANEL_SAMSUNG_S6E8FC0 is not set
# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set
# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set
# CONFIG_DRM_PANEL_SHARP_LQ079L1SX01 is not set
# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set
# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set
# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set
# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set
# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set
# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set
# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set
# CONFIG_DRM_PANEL_SONY_TD4353_JDI is not set
# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set
# CONFIG_DRM_PANEL_STARTEK_KD070FHFID015 is not set
CONFIG_DRM_PANEL_EDP=y
# CONFIG_DRM_PANEL_SIMPLE is not set
# CONFIG_DRM_PANEL_SUMMIT is not set
# CONFIG_DRM_PANEL_SYNAPTICS_R63353 is not set
# CONFIG_DRM_PANEL_SYNAPTICS_TDDI is not set
# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set
# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set
# CONFIG_DRM_PANEL_TPO_TPG110 is not set
# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set
# CONFIG_DRM_PANEL_VISIONOX_G2647FB105 is not set
# CONFIG_DRM_PANEL_VISIONOX_R66451 is not set
# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set
# CONFIG_DRM_PANEL_VISIONOX_RM692E5 is not set
# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 is not set
# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set
# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set
# end of Display Panels

# CONFIG_DRM_QXL is not set
# CONFIG_DRM_RADEON is not set
# CONFIG_DRM_ST7571 is not set
# CONFIG_DRM_ST7586 is not set
# CONFIG_DRM_ST7735R is not set
# CONFIG_DRM_ST7920 is not set
# CONFIG_DRM_SSD130X is not set

#
# Drivers for system framebuffers
#
CONFIG_DRM_SYSFB_HELPER=y
CONFIG_DRM_SIMPLEDRM=y
# CONFIG_DRM_VESADRM is not set
# end of Drivers for system framebuffers

# CONFIG_DRM_APPLETBDRM is not set
# CONFIG_DRM_ARCPGU is not set
CONFIG_DRM_BOCHS=y
CONFIG_DRM_CIRRUS_QEMU=y
CONFIG_DRM_GM12U320=y
# CONFIG_DRM_PANEL_MIPI_DBI is not set
# CONFIG_DRM_PIXPAPER is not set
# CONFIG_TINYDRM_HX8357D is not set
# CONFIG_TINYDRM_ILI9163 is not set
# CONFIG_TINYDRM_ILI9225 is not set
# CONFIG_TINYDRM_ILI9341 is not set
# CONFIG_TINYDRM_ILI9486 is not set
# CONFIG_TINYDRM_MI0283QT is not set
# CONFIG_TINYDRM_REPAPER is not set
# CONFIG_TINYDRM_SHARP_MEMORY is not set
CONFIG_DRM_UDL=y
# CONFIG_DRM_VBOXVIDEO is not set
CONFIG_DRM_VGEM=y
CONFIG_DRM_VIRTIO_GPU=y
CONFIG_DRM_VIRTIO_GPU_KMS=y
CONFIG_DRM_VKMS=y
CONFIG_DRM_VMWGFX=y
# CONFIG_DRM_VMWGFX_MKSSTATS is not set
# CONFIG_DRM_XE is not set
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y

#
# Frame buffer Devices
#
CONFIG_FB=y
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_VGA16=y
# CONFIG_FB_UVESA is not set
CONFIG_FB_VESA=y
# CONFIG_FB_N411 is not set
# CONFIG_FB_OPENCORES is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_I740 is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_VIA is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_CARMINE is not set
# CONFIG_FB_SMSCUFX is not set
# CONFIG_FB_UDL is not set
# CONFIG_FB_IBM_GXT4500 is not set
CONFIG_FB_VIRTUAL=y
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_SSD1307 is not set
# CONFIG_FB_SM712 is not set
CONFIG_FB_CORE=y
CONFIG_FB_NOTIFY=y
CONFIG_FB_DEVICE=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
# CONFIG_FB_FOREIGN_ENDIAN is not set
CONFIG_FB_SYSMEM_FOPS=y
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_IOMEM_FOPS=y
CONFIG_FB_IOMEM_HELPERS=y
CONFIG_FB_SYSMEM_HELPERS=y
CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
CONFIG_FB_TILEBLITTING=y
# end of Frame buffer Devices

#
# Backlight & LCD device support
#
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_L4F00242T03 is not set
# CONFIG_LCD_LMS283GF05 is not set
# CONFIG_LCD_LTV350QV is not set
# CONFIG_LCD_ILI922X is not set
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_TDO24M is not set
# CONFIG_LCD_VGG2432A4 is not set
# CONFIG_LCD_PLATFORM is not set
# CONFIG_LCD_AMS369FG06 is not set
# CONFIG_LCD_LMS501KF03 is not set
# CONFIG_LCD_HX8357 is not set
# CONFIG_LCD_OTM3225A is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_AW99706 is not set
# CONFIG_BACKLIGHT_KTD253 is not set
# CONFIG_BACKLIGHT_KTD2801 is not set
# CONFIG_BACKLIGHT_KTZ8866 is not set
# CONFIG_BACKLIGHT_MAX25014 is not set
# CONFIG_BACKLIGHT_MT6370 is not set
# CONFIG_BACKLIGHT_APPLE is not set
# CONFIG_BACKLIGHT_QCOM_WLED is not set
# CONFIG_BACKLIGHT_SAHARA is not set
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_ADP8870 is not set
# CONFIG_BACKLIGHT_LM3509 is not set
# CONFIG_BACKLIGHT_LM3639 is not set
# CONFIG_BACKLIGHT_PANDORA is not set
# CONFIG_BACKLIGHT_GPIO is not set
# CONFIG_BACKLIGHT_LV5207LP is not set
# CONFIG_BACKLIGHT_BD6107 is not set
# CONFIG_BACKLIGHT_ARCXCNN is not set
# CONFIG_BACKLIGHT_LED is not set
# end of Backlight & LCD device support

CONFIG_VGASTATE=y
CONFIG_VIDEOMODE_HELPERS=y
CONFIG_HDMI=y
# CONFIG_FIRMWARE_EDID is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=80
CONFIG_DUMMY_CONSOLE_ROWS=25
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set
# end of Console display driver support

CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_MONO_FILE="drivers/video/logo/logo_linux_mono.pbm"
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_VGA16_FILE="drivers/video/logo/logo_linux_vga16.ppm"
# CONFIG_LOGO_LINUX_CLUT224 is not set
# CONFIG_TRACE_GPU_MEM is not set
# end of Graphics support

# CONFIG_DRM_ACCEL is not set
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
CONFIG_SND_HWDEP=y
CONFIG_SND_SEQ_DEVICE=y
CONFIG_SND_RAWMIDI=y
CONFIG_SND_UMP=y
CONFIG_SND_UMP_LEGACY_RAWMIDI=y
CONFIG_SND_JACK=y
CONFIG_SND_JACK_INPUT_DEV=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_PCM_TIMER=y
CONFIG_SND_HRTIMER=y
# CONFIG_SND_DYNAMIC_MINORS is not set
# CONFIG_SND_SUPPORT_OLD_API is not set
CONFIG_SND_PROC_FS=y
CONFIG_SND_VERBOSE_PROCFS=y
CONFIG_SND_CTL_FAST_LOOKUP=y
# CONFIG_SND_DEBUG is not set
# CONFIG_SND_CTL_INPUT_VALIDATION is not set
# CONFIG_SND_UTIMER is not set
CONFIG_SND_VMASTER=y
CONFIG_SND_DMA_SGBUF=y
CONFIG_SND_CTL_LED=y
CONFIG_SND_SEQUENCER=y
CONFIG_SND_SEQ_DUMMY=y
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
CONFIG_SND_SEQ_MIDI_EVENT=y
CONFIG_SND_SEQ_MIDI=y
CONFIG_SND_SEQ_VIRMIDI=y
# CONFIG_SND_SEQ_UMP is not set
CONFIG_SND_DRIVERS=y
# CONFIG_SND_PCSP is not set
CONFIG_SND_DUMMY=y
CONFIG_SND_ALOOP=y
# CONFIG_SND_PCMTEST is not set
CONFIG_SND_VIRMIDI=y
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_MTS64 is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_SERIAL_GENERIC is not set
# CONFIG_SND_MPU401 is not set
# CONFIG_SND_PORTMAN2X4 is not set
CONFIG_SND_PCI=y
# CONFIG_SND_AD1889 is not set
# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ASIHPI is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
# CONFIG_SND_AU8810 is not set
# CONFIG_SND_AU8820 is not set
# CONFIG_SND_AU8830 is not set
# CONFIG_SND_AW2 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_BT87X is not set
# CONFIG_SND_CA0106 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_OXYGEN is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CTXFI is not set
# CONFIG_SND_DARLA20 is not set
# CONFIG_SND_GINA20 is not set
# CONFIG_SND_LAYLA20 is not set
# CONFIG_SND_DARLA24 is not set
# CONFIG_SND_GINA24 is not set
# CONFIG_SND_LAYLA24 is not set
# CONFIG_SND_MONA is not set
# CONFIG_SND_MIA is not set
# CONFIG_SND_ECHO3G is not set
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_INDIGOIOX is not set
# CONFIG_SND_INDIGODJX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
# CONFIG_SND_FM801 is not set
# CONFIG_SND_HDSP is not set
# CONFIG_SND_HDSPM is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
# CONFIG_SND_INTEL8X0 is not set
# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_LOLA is not set
# CONFIG_SND_LX6464ES is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_SE6X is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VIRTUOSO is not set
# CONFIG_SND_VX222 is not set
# CONFIG_SND_YMFPCI is not set

#
# HD-Audio
#
CONFIG_SND_HDA=y
CONFIG_SND_HDA_HWDEP=y
CONFIG_SND_HDA_RECONFIG=y
CONFIG_SND_HDA_INPUT_BEEP=y
CONFIG_SND_HDA_INPUT_BEEP_MODE=1
CONFIG_SND_HDA_PATCH_LOADER=y
CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
# CONFIG_SND_HDA_CTL_DEV_ID is not set
CONFIG_SND_HDA_PREALLOC_SIZE=0
CONFIG_SND_HDA_INTEL=y
# CONFIG_SND_HDA_ACPI is not set
CONFIG_SND_HDA_GENERIC_LEDS=y
CONFIG_SND_HDA_CODEC_ANALOG=y
CONFIG_SND_HDA_CODEC_SIGMATEL=y
CONFIG_SND_HDA_CODEC_VIA=y
CONFIG_SND_HDA_CODEC_CONEXANT=y
# CONFIG_SND_HDA_CODEC_SENARYTECH is not set
CONFIG_SND_HDA_CODEC_CA0110=y
CONFIG_SND_HDA_CODEC_CA0132=y
# CONFIG_SND_HDA_CODEC_CA0132_DSP is not set
CONFIG_SND_HDA_CODEC_CMEDIA=y
# CONFIG_SND_HDA_CODEC_CM9825 is not set
CONFIG_SND_HDA_CODEC_SI3054=y
CONFIG_SND_HDA_GENERIC=y
CONFIG_SND_HDA_CODEC_REALTEK=y
# CONFIG_SND_HDA_CODEC_ALC260 is not set
# CONFIG_SND_HDA_CODEC_ALC262 is not set
# CONFIG_SND_HDA_CODEC_ALC268 is not set
# CONFIG_SND_HDA_CODEC_ALC269 is not set
# CONFIG_SND_HDA_CODEC_ALC662 is not set
# CONFIG_SND_HDA_CODEC_ALC680 is not set
# CONFIG_SND_HDA_CODEC_ALC861 is not set
# CONFIG_SND_HDA_CODEC_ALC861VD is not set
# CONFIG_SND_HDA_CODEC_ALC880 is not set
# CONFIG_SND_HDA_CODEC_ALC882 is not set
CONFIG_SND_HDA_CODEC_CIRRUS=y
# CONFIG_SND_HDA_CODEC_CS420X is not set
# CONFIG_SND_HDA_CODEC_CS421X is not set
# CONFIG_SND_HDA_CODEC_CS8409 is not set
CONFIG_SND_HDA_CODEC_HDMI=y
# CONFIG_SND_HDA_CODEC_HDMI_GENERIC is not set
# CONFIG_SND_HDA_CODEC_HDMI_SIMPLE is not set
# CONFIG_SND_HDA_CODEC_HDMI_INTEL is not set
# CONFIG_SND_HDA_CODEC_HDMI_ATI is not set
# CONFIG_SND_HDA_CODEC_HDMI_NVIDIA is not set
# CONFIG_SND_HDA_CODEC_HDMI_NVIDIA_MCP is not set
# CONFIG_SND_HDA_CODEC_HDMI_TEGRA is not set
# CONFIG_SND_HDA_SCODEC_CS35L56_I2C is not set
# CONFIG_SND_HDA_SCODEC_CS35L56_SPI is not set
CONFIG_SND_HDA_CORE=y
CONFIG_SND_HDA_COMPONENT=y
CONFIG_SND_HDA_I915=y
CONFIG_SND_INTEL_NHLT=y
CONFIG_SND_INTEL_DSP_CONFIG=y
CONFIG_SND_INTEL_SOUNDWIRE_ACPI=y
# end of HD-Audio

# CONFIG_SND_SPI is not set
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
CONFIG_SND_USB_AUDIO_MIDI_V2=y
CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y
CONFIG_SND_USB_UA101=y
CONFIG_SND_USB_USX2Y=y
CONFIG_SND_USB_CAIAQ=y
CONFIG_SND_USB_CAIAQ_INPUT=y
CONFIG_SND_USB_US122L=y
# CONFIG_SND_USB_US144MKII is not set
CONFIG_SND_USB_6FIRE=y
CONFIG_SND_USB_HIFACE=y
CONFIG_SND_BCD2000=y
CONFIG_SND_USB_LINE6=y
CONFIG_SND_USB_POD=y
CONFIG_SND_USB_PODHD=y
CONFIG_SND_USB_TONEPORT=y
CONFIG_SND_USB_VARIAX=y
# CONFIG_SND_FIREWIRE is not set
CONFIG_SND_PCMCIA=y
# CONFIG_SND_VXPOCKET is not set
# CONFIG_SND_PDAUDIOCF is not set
CONFIG_SND_SOC=y
# CONFIG_SND_SOC_USB is not set

#
# Analog Devices
#
# CONFIG_SND_SOC_ADI_AXI_I2S is not set
# CONFIG_SND_SOC_ADI_AXI_SPDIF is not set
# end of Analog Devices

#
# AMD
#
# CONFIG_SND_SOC_AMD_ACP is not set
# CONFIG_SND_SOC_AMD_ACP3x is not set
# CONFIG_SND_SOC_AMD_RENOIR is not set
# CONFIG_SND_SOC_AMD_ACP5x is not set
# CONFIG_SND_SOC_AMD_ACP6x is not set
# CONFIG_SND_AMD_ACP_CONFIG is not set
# CONFIG_SND_SOC_AMD_ACP_COMMON is not set
# end of AMD

#
# Apple
#
# end of Apple

#
# Atmel
#
# CONFIG_SND_SOC_MIKROE_PROTO is not set
# end of Atmel

#
# Au1x
#
# end of Au1x

#
# Broadcom
#
# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set
# end of Broadcom

#
# Cirrus Logic
#
# end of Cirrus Logic

#
# DesignWare
#
# CONFIG_SND_DESIGNWARE_I2S is not set
# end of DesignWare

#
# Freescale
#

#
# Common SoC Audio options for Freescale CPUs:
#
# CONFIG_SND_SOC_FSL_ASRC is not set
# CONFIG_SND_SOC_FSL_SAI is not set
# CONFIG_SND_SOC_FSL_AUDMIX is not set
# CONFIG_SND_SOC_FSL_SSI is not set
# CONFIG_SND_SOC_FSL_SPDIF is not set
# CONFIG_SND_SOC_FSL_ESAI is not set
# CONFIG_SND_SOC_FSL_MICFIL is not set
# CONFIG_SND_SOC_FSL_XCVR is not set
# CONFIG_SND_SOC_IMX_AUDMUX is not set
# end of Freescale

#
# Google
#
# CONFIG_SND_SOC_CHV3_I2S is not set
# end of Google

#
# Hisilicon
#
# CONFIG_SND_I2S_HI6210_I2S is not set
# end of Hisilicon

#
# JZ4740
#
# end of JZ4740

#
# Kirkwood
#
# end of Kirkwood

#
# Loongson
#
# end of Loongson

#
# Intel
#
# CONFIG_SND_SOC_INTEL_SST_TOPLEVEL is not set
# CONFIG_SND_SOC_INTEL_AVS is not set
# end of Intel

#
# Mediatek
#
# CONFIG_SND_SOC_MTK_BTCVSD is not set
# end of Mediatek

#
# PXA
#
# end of PXA

#
# SoundWire (SDCA)
#
# CONFIG_SND_SOC_SDCA is not set
CONFIG_SND_SOC_SDCA_OPTIONAL=y
# end of SoundWire (SDCA)

#
# ST SPEAr
#
# end of ST SPEAr

#
# Spreadtrum
#
# end of Spreadtrum

#
# STMicroelectronics STM32
#
# end of STMicroelectronics STM32

#
# Tegra
#
# end of Tegra

#
# Xilinx
#
# CONFIG_SND_SOC_XILINX_I2S is not set
# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set
# CONFIG_SND_SOC_XILINX_SPDIF is not set
# end of Xilinx

#
# Xtensa
#
# CONFIG_SND_SOC_XTFPGA_I2S is not set
# end of Xtensa

# CONFIG_SND_SOC_SOF_TOPLEVEL is not set
CONFIG_SND_SOC_I2C_AND_SPI=y

#
# CODEC drivers
#
# CONFIG_SND_SOC_AC97_CODEC is not set
# CONFIG_SND_SOC_ADAU1372_I2C is not set
# CONFIG_SND_SOC_ADAU1372_SPI is not set
# CONFIG_SND_SOC_ADAU1373 is not set
# CONFIG_SND_SOC_ADAU1701 is not set
# CONFIG_SND_SOC_ADAU1761_I2C is not set
# CONFIG_SND_SOC_ADAU1761_SPI is not set
# CONFIG_SND_SOC_ADAU7002 is not set
# CONFIG_SND_SOC_ADAU7118_HW is not set
# CONFIG_SND_SOC_ADAU7118_I2C is not set
# CONFIG_SND_SOC_AK4104 is not set
# CONFIG_SND_SOC_AK4118 is not set
# CONFIG_SND_SOC_AK4375 is not set
# CONFIG_SND_SOC_AK4458 is not set
# CONFIG_SND_SOC_AK4554 is not set
# CONFIG_SND_SOC_AK4613 is not set
# CONFIG_SND_SOC_AK4619 is not set
# CONFIG_SND_SOC_AK4642 is not set
# CONFIG_SND_SOC_AK5386 is not set
# CONFIG_SND_SOC_AK5558 is not set
# CONFIG_SND_SOC_ALC5623 is not set
# CONFIG_SND_SOC_AUDIO_IIO_AUX is not set
# CONFIG_SND_SOC_AW8738 is not set
# CONFIG_SND_SOC_AW88395 is not set
# CONFIG_SND_SOC_AW88166 is not set
# CONFIG_SND_SOC_AW88261 is not set
# CONFIG_SND_SOC_AW88081 is not set
# CONFIG_SND_SOC_AW87390 is not set
# CONFIG_SND_SOC_AW88399 is not set
# CONFIG_SND_SOC_BD28623 is not set
# CONFIG_SND_SOC_BT_SCO is not set
# CONFIG_SND_SOC_CHV3_CODEC is not set
# CONFIG_SND_SOC_CS35L32 is not set
# CONFIG_SND_SOC_CS35L33 is not set
# CONFIG_SND_SOC_CS35L34 is not set
# CONFIG_SND_SOC_CS35L35 is not set
# CONFIG_SND_SOC_CS35L36 is not set
# CONFIG_SND_SOC_CS35L41_SPI is not set
# CONFIG_SND_SOC_CS35L41_I2C is not set
# CONFIG_SND_SOC_CS35L45_SPI is not set
# CONFIG_SND_SOC_CS35L45_I2C is not set
# CONFIG_SND_SOC_CS35L56_I2C is not set
# CONFIG_SND_SOC_CS35L56_SPI is not set
# CONFIG_SND_SOC_CS35L56_SDW is not set
# CONFIG_SND_SOC_CS42L42 is not set
# CONFIG_SND_SOC_CS42L42_SDW is not set
# CONFIG_SND_SOC_CS42L51_I2C is not set
# CONFIG_SND_SOC_CS42L52 is not set
# CONFIG_SND_SOC_CS42L56 is not set
# CONFIG_SND_SOC_CS42L73 is not set
# CONFIG_SND_SOC_CS42L83 is not set
# CONFIG_SND_SOC_CS42L84 is not set
# CONFIG_SND_SOC_CS4234 is not set
# CONFIG_SND_SOC_CS4265 is not set
# CONFIG_SND_SOC_CS4270 is not set
# CONFIG_SND_SOC_CS4271_I2C is not set
# CONFIG_SND_SOC_CS4271_SPI is not set
# CONFIG_SND_SOC_CS42XX8_SPI is not set
# CONFIG_SND_SOC_CS42XX8_I2C is not set
# CONFIG_SND_SOC_CS43130 is not set
# CONFIG_SND_SOC_CS4341 is not set
# CONFIG_SND_SOC_CS4349 is not set
# CONFIG_SND_SOC_CS48L32 is not set
# CONFIG_SND_SOC_CS53L30 is not set
# CONFIG_SND_SOC_CS530X_I2C is not set
# CONFIG_SND_SOC_CS530X_SPI is not set
# CONFIG_SND_SOC_CX2072X is not set
# CONFIG_SND_SOC_DA7213 is not set
# CONFIG_SND_SOC_DMIC is not set
# CONFIG_SND_SOC_ES7134 is not set
# CONFIG_SND_SOC_ES7241 is not set
# CONFIG_SND_SOC_ES8311 is not set
# CONFIG_SND_SOC_ES8316 is not set
# CONFIG_SND_SOC_ES8323 is not set
# CONFIG_SND_SOC_ES8326 is not set
# CONFIG_SND_SOC_ES8328_I2C is not set
# CONFIG_SND_SOC_ES8328_SPI is not set
# CONFIG_SND_SOC_ES8375 is not set
# CONFIG_SND_SOC_ES8389 is not set
# CONFIG_SND_SOC_FS210X is not set
# CONFIG_SND_SOC_GTM601 is not set
# CONFIG_SND_SOC_HDA is not set
# CONFIG_SND_SOC_ICS43432 is not set
# CONFIG_SND_SOC_IDT821034 is not set
# CONFIG_SND_SOC_MAX98088 is not set
# CONFIG_SND_SOC_MAX98090 is not set
# CONFIG_SND_SOC_MAX98357A is not set
# CONFIG_SND_SOC_MAX98504 is not set
# CONFIG_SND_SOC_MAX9867 is not set
# CONFIG_SND_SOC_MAX98927 is not set
# CONFIG_SND_SOC_MAX98520 is not set
# CONFIG_SND_SOC_MAX98363 is not set
# CONFIG_SND_SOC_MAX98373_I2C is not set
# CONFIG_SND_SOC_MAX98373_SDW is not set
# CONFIG_SND_SOC_MAX98388 is not set
# CONFIG_SND_SOC_MAX98390 is not set
# CONFIG_SND_SOC_MAX98396 is not set
# CONFIG_SND_SOC_MAX9860 is not set
# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set
# CONFIG_SND_SOC_PCM1681 is not set
# CONFIG_SND_SOC_PCM1754 is not set
# CONFIG_SND_SOC_PCM1789_I2C is not set
# CONFIG_SND_SOC_PCM179X_I2C is not set
# CONFIG_SND_SOC_PCM179X_SPI is not set
# CONFIG_SND_SOC_PCM186X_I2C is not set
# CONFIG_SND_SOC_PCM186X_SPI is not set
# CONFIG_SND_SOC_PCM3060_I2C is not set
# CONFIG_SND_SOC_PCM3060_SPI is not set
# CONFIG_SND_SOC_PCM3168A_I2C is not set
# CONFIG_SND_SOC_PCM3168A_SPI is not set
# CONFIG_SND_SOC_PCM5102A is not set
# CONFIG_SND_SOC_PCM512x_I2C is not set
# CONFIG_SND_SOC_PCM512x_SPI is not set
# CONFIG_SND_SOC_PCM6240 is not set
# CONFIG_SND_SOC_PEB2466 is not set
# CONFIG_SND_SOC_PM4125_SDW is not set
# CONFIG_SND_SOC_RT1017_SDCA_SDW is not set
# CONFIG_SND_SOC_RT1308_SDW is not set
# CONFIG_SND_SOC_RT1316_SDW is not set
# CONFIG_SND_SOC_RT1318_SDW is not set
# CONFIG_SND_SOC_RT1320_SDW is not set
# CONFIG_SND_SOC_RT5575 is not set
# CONFIG_SND_SOC_RT5616 is not set
# CONFIG_SND_SOC_RT5631 is not set
# CONFIG_SND_SOC_RT5640 is not set
# CONFIG_SND_SOC_RT5659 is not set
# CONFIG_SND_SOC_RT5682_SDW is not set
# CONFIG_SND_SOC_RT700_SDW is not set
# CONFIG_SND_SOC_RT711_SDW is not set
# CONFIG_SND_SOC_RT711_SDCA_SDW is not set
# CONFIG_SND_SOC_RT712_SDCA_SDW is not set
# CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW is not set
# CONFIG_SND_SOC_RT721_SDCA_SDW is not set
# CONFIG_SND_SOC_RT722_SDCA_SDW is not set
# CONFIG_SND_SOC_RT715_SDW is not set
# CONFIG_SND_SOC_RT715_SDCA_SDW is not set
# CONFIG_SND_SOC_RT9120 is not set
# CONFIG_SND_SOC_RT9123 is not set
# CONFIG_SND_SOC_RT9123P is not set
# CONFIG_SND_SOC_RTQ9124 is not set
# CONFIG_SND_SOC_RTQ9128 is not set
# CONFIG_SND_SOC_SDW_MOCKUP is not set
# CONFIG_SND_SOC_SGTL5000 is not set
# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set
# CONFIG_SND_SOC_SIMPLE_MUX is not set
# CONFIG_SND_SOC_SMA1303 is not set
# CONFIG_SND_SOC_SMA1307 is not set
# CONFIG_SND_SOC_SPDIF is not set
# CONFIG_SND_SOC_SRC4XXX_I2C is not set
# CONFIG_SND_SOC_SSM2305 is not set
# CONFIG_SND_SOC_SSM2518 is not set
# CONFIG_SND_SOC_SSM2602_SPI is not set
# CONFIG_SND_SOC_SSM2602_I2C is not set
# CONFIG_SND_SOC_SSM3515 is not set
# CONFIG_SND_SOC_SSM4567 is not set
# CONFIG_SND_SOC_STA32X is not set
# CONFIG_SND_SOC_STA350 is not set
# CONFIG_SND_SOC_STI_SAS is not set
# CONFIG_SND_SOC_TAS2552 is not set
# CONFIG_SND_SOC_TAS2562 is not set
# CONFIG_SND_SOC_TAS2764 is not set
# CONFIG_SND_SOC_TAS2770 is not set
# CONFIG_SND_SOC_TAS2780 is not set
# CONFIG_SND_SOC_TAS2781_I2C is not set
# CONFIG_SND_SOC_TAS5086 is not set
# CONFIG_SND_SOC_TAS571X is not set
# CONFIG_SND_SOC_TAS5720 is not set
# CONFIG_SND_SOC_TAS5805M is not set
# CONFIG_SND_SOC_TAS6424 is not set
# CONFIG_SND_SOC_TAS675X is not set
# CONFIG_SND_SOC_TDA7419 is not set
# CONFIG_SND_SOC_TFA9879 is not set
# CONFIG_SND_SOC_TFA989X is not set
# CONFIG_SND_SOC_TLV320ADC3XXX is not set
# CONFIG_SND_SOC_TLV320AIC23_I2C is not set
# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
# CONFIG_SND_SOC_TLV320AIC31XX is not set
# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set
# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set
# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set
# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set
# CONFIG_SND_SOC_TLV320ADCX140 is not set
# CONFIG_SND_SOC_TS3A227E is not set
# CONFIG_SND_SOC_TSCS42XX is not set
# CONFIG_SND_SOC_TSCS454 is not set
# CONFIG_SND_SOC_UDA1334 is not set
# CONFIG_SND_SOC_UDA1342 is not set
# CONFIG_SND_SOC_UDA1380 is not set
# CONFIG_SND_SOC_WCD937X_SDW is not set
# CONFIG_SND_SOC_WCD938X_SDW is not set
# CONFIG_SND_SOC_WCD939X_SDW is not set
# CONFIG_SND_SOC_WM8510 is not set
# CONFIG_SND_SOC_WM8523 is not set
# CONFIG_SND_SOC_WM8524 is not set
# CONFIG_SND_SOC_WM8580 is not set
# CONFIG_SND_SOC_WM8711 is not set
# CONFIG_SND_SOC_WM8728 is not set
# CONFIG_SND_SOC_WM8731_I2C is not set
# CONFIG_SND_SOC_WM8731_SPI is not set
# CONFIG_SND_SOC_WM8737 is not set
# CONFIG_SND_SOC_WM8741 is not set
# CONFIG_SND_SOC_WM8750 is not set
# CONFIG_SND_SOC_WM8753 is not set
# CONFIG_SND_SOC_WM8770 is not set
# CONFIG_SND_SOC_WM8776 is not set
# CONFIG_SND_SOC_WM8782 is not set
# CONFIG_SND_SOC_WM8804_I2C is not set
# CONFIG_SND_SOC_WM8804_SPI is not set
# CONFIG_SND_SOC_WM8903 is not set
# CONFIG_SND_SOC_WM8904 is not set
# CONFIG_SND_SOC_WM8940 is not set
# CONFIG_SND_SOC_WM8960 is not set
# CONFIG_SND_SOC_WM8961 is not set
# CONFIG_SND_SOC_WM8962 is not set
# CONFIG_SND_SOC_WM8974 is not set
# CONFIG_SND_SOC_WM8978 is not set
# CONFIG_SND_SOC_WM8985 is not set
# CONFIG_SND_SOC_WSA881X is not set
# CONFIG_SND_SOC_WSA883X is not set
# CONFIG_SND_SOC_WSA884X is not set
# CONFIG_SND_SOC_ZL38060 is not set
# CONFIG_SND_SOC_MAX9759 is not set
# CONFIG_SND_SOC_MT6351 is not set
# CONFIG_SND_SOC_MT6357 is not set
# CONFIG_SND_SOC_MT6358 is not set
# CONFIG_SND_SOC_MT6660 is not set
# CONFIG_SND_SOC_NAU8315 is not set
# CONFIG_SND_SOC_NAU8325 is not set
# CONFIG_SND_SOC_NAU8540 is not set
# CONFIG_SND_SOC_NAU8810 is not set
# CONFIG_SND_SOC_NAU8821 is not set
# CONFIG_SND_SOC_NAU8822 is not set
# CONFIG_SND_SOC_NAU8824 is not set
# CONFIG_SND_SOC_NTP8918 is not set
# CONFIG_SND_SOC_NTP8835 is not set
# CONFIG_SND_SOC_TPA6130A2 is not set
# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set
# CONFIG_SND_SOC_LPASS_VA_MACRO is not set
# CONFIG_SND_SOC_LPASS_RX_MACRO is not set
# CONFIG_SND_SOC_LPASS_TX_MACRO is not set
# end of CODEC drivers

#
# Generic drivers
#
# CONFIG_SND_SIMPLE_CARD is not set
# CONFIG_SND_AUDIO_GRAPH_CARD is not set
# CONFIG_SND_AUDIO_GRAPH_CARD2 is not set
# CONFIG_SND_TEST_COMPONENT is not set
# end of Generic drivers

CONFIG_SND_X86=y
# CONFIG_HDMI_LPE_AUDIO is not set
CONFIG_SND_VIRTIO=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
CONFIG_HID_BATTERY_STRENGTH=y
CONFIG_HIDRAW=y
CONFIG_UHID=y
CONFIG_HID_GENERIC=y
CONFIG_HID_HAPTIC=y

#
# Special HID drivers
#
CONFIG_HID_A4TECH=y
CONFIG_HID_ACCUTOUCH=y
CONFIG_HID_ACRUX=y
CONFIG_HID_ACRUX_FF=y
CONFIG_HID_APPLE=y
CONFIG_HID_APPLEIR=y
# CONFIG_HID_APPLETB_BL is not set
# CONFIG_HID_APPLETB_KBD is not set
CONFIG_HID_ASUS=y
CONFIG_HID_AUREAL=y
CONFIG_HID_BELKIN=y
CONFIG_HID_BETOP_FF=y
CONFIG_HID_BIGBEN_FF=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CORSAIR=y
CONFIG_HID_COUGAR=y
CONFIG_HID_MACALLY=y
CONFIG_HID_PRODIKEYS=y
CONFIG_HID_CMEDIA=y
CONFIG_HID_CP2112=y
CONFIG_HID_CREATIVE_SB0540=y
CONFIG_HID_CYPRESS=y
CONFIG_HID_DRAGONRISE=y
CONFIG_DRAGONRISE_FF=y
CONFIG_HID_EMS_FF=y
CONFIG_HID_ELAN=y
CONFIG_HID_ELECOM=y
CONFIG_HID_ELO=y
CONFIG_HID_EVISION=y
CONFIG_HID_EZKEY=y
CONFIG_HID_FT260=y
CONFIG_HID_GEMBIRD=y
CONFIG_HID_GFRM=y
CONFIG_HID_GLORIOUS=y
CONFIG_HID_HOLTEK=y
CONFIG_HOLTEK_FF=y
CONFIG_HID_VIVALDI_COMMON=y
# CONFIG_HID_GOODIX_SPI is not set
CONFIG_HID_GOOGLE_STADIA_FF=y
CONFIG_HID_VIVALDI=y
CONFIG_HID_GT683R=y
CONFIG_HID_KEYTOUCH=y
CONFIG_HID_KYE=y
# CONFIG_HID_KYSONA is not set
CONFIG_HID_UCLOGIC=y
CONFIG_HID_WALTOP=y
CONFIG_HID_VIEWSONIC=y
CONFIG_HID_VRC2=y
CONFIG_HID_XIAOMI=y
CONFIG_HID_GYRATION=y
CONFIG_HID_ICADE=y
CONFIG_HID_ITE=y
CONFIG_HID_JABRA=y
CONFIG_HID_TWINHAN=y
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LCPOWER=y
CONFIG_HID_LED=y
CONFIG_HID_LENOVO=y
# CONFIG_HID_LENOVO_GO is not set
# CONFIG_HID_LENOVO_GO_S is not set
CONFIG_HID_LETSKETCH=y
CONFIG_HID_LOGITECH=y
CONFIG_HID_LOGITECH_DJ=y
CONFIG_HID_LOGITECH_HIDPP=y
CONFIG_LOGITECH_FF=y
CONFIG_LOGIRUMBLEPAD2_FF=y
CONFIG_LOGIG940_FF=y
CONFIG_LOGIWHEELS_FF=y
CONFIG_HID_MAGICMOUSE=y
CONFIG_HID_MALTRON=y
CONFIG_HID_MAYFLASH=y
CONFIG_HID_MEGAWORLD_FF=y
# CONFIG_HID_RAKK is not set
CONFIG_HID_REDRAGON=y
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_HID_MULTITOUCH=y
CONFIG_HID_NINTENDO=y
CONFIG_NINTENDO_FF=y
CONFIG_HID_NTI=y
CONFIG_HID_NTRIG=y
CONFIG_HID_NVIDIA_SHIELD=y
CONFIG_NVIDIA_SHIELD_FF=y
CONFIG_HID_ORTEK=y
# CONFIG_HID_OXP is not set
CONFIG_HID_PANTHERLORD=y
CONFIG_PANTHERLORD_FF=y
CONFIG_HID_PENMOUNT=y
CONFIG_HID_PETALYNX=y
CONFIG_HID_PICOLCD=y
CONFIG_HID_PICOLCD_FB=y
CONFIG_HID_PICOLCD_BACKLIGHT=y
CONFIG_HID_PICOLCD_LCD=y
CONFIG_HID_PICOLCD_LEDS=y
CONFIG_HID_PICOLCD_CIR=y
CONFIG_HID_PLANTRONICS=y
CONFIG_HID_PLAYSTATION=y
CONFIG_PLAYSTATION_FF=y
CONFIG_HID_PXRC=y
# CONFIG_HID_RAPOO is not set
CONFIG_HID_RAZER=y
CONFIG_HID_PRIMAX=y
CONFIG_HID_RETRODE=y
CONFIG_HID_ROCCAT=y
CONFIG_HID_SAITEK=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SEMITEK=y
CONFIG_HID_SIGMAMICRO=y
CONFIG_HID_SONY=y
CONFIG_SONY_FF=y
CONFIG_HID_SPEEDLINK=y
CONFIG_HID_STEAM=y
CONFIG_STEAM_FF=y
CONFIG_HID_STEELSERIES=y
CONFIG_HID_SUNPLUS=y
CONFIG_HID_RMI=y
CONFIG_HID_GREENASIA=y
CONFIG_GREENASIA_FF=y
CONFIG_HID_SMARTJOYPLUS=y
CONFIG_SMARTJOYPLUS_FF=y
CONFIG_HID_TIVO=y
CONFIG_HID_TOPSEED=y
CONFIG_HID_TOPRE=y
CONFIG_HID_THINGM=y
CONFIG_HID_THRUSTMASTER=y
CONFIG_THRUSTMASTER_FF=y
CONFIG_HID_UDRAW_PS3=y
CONFIG_HID_U2FZERO=y
# CONFIG_HID_UNIVERSAL_PIDFF is not set
CONFIG_HID_WACOM=y
CONFIG_HID_WIIMOTE=y
# CONFIG_HID_WINWING is not set
CONFIG_HID_XINMO=y
CONFIG_HID_ZEROPLUS=y
CONFIG_ZEROPLUS_FF=y
CONFIG_HID_ZYDACRON=y
CONFIG_HID_SENSOR_HUB=y
CONFIG_HID_SENSOR_CUSTOM_SENSOR=y
CONFIG_HID_ALPS=y
CONFIG_HID_MCP2200=y
CONFIG_HID_MCP2221=y
CONFIG_HID_HUAWEI=y
# end of Special HID drivers

#
# HID-BPF support
#
# end of HID-BPF support

CONFIG_I2C_HID=y
CONFIG_I2C_HID_ACPI=y
CONFIG_I2C_HID_OF=y
# CONFIG_I2C_HID_OF_ELAN is not set
# CONFIG_I2C_HID_OF_GOODIX is not set
CONFIG_I2C_HID_CORE=y

#
# Intel ISH HID support
#
CONFIG_INTEL_ISH_HID=y
CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER=y
# end of Intel ISH HID support

#
# AMD SFH HID Support
#
CONFIG_AMD_SFH_HID=y
# end of AMD SFH HID Support

#
# Surface System Aggregator Module HID support
#
CONFIG_SURFACE_HID=y
CONFIG_SURFACE_KBD=y
# end of Surface System Aggregator Module HID support

CONFIG_SURFACE_HID_CORE=y

#
# Intel THC HID Support
#
# CONFIG_INTEL_THC_HID is not set
# end of Intel THC HID Support

#
# USB HID support
#
CONFIG_USB_HID=y
CONFIG_HID_PID=y
CONFIG_USB_HIDDEV=y
# end of USB HID support

CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_LED_TRIG=y
CONFIG_USB_ULPI_BUS=y
CONFIG_USB_CONN_GPIO=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
CONFIG_USB_PCI=y
CONFIG_USB_PCI_AMD=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y

#
# Miscellaneous USB options
#
CONFIG_USB_DEFAULT_PERSIST=y
CONFIG_USB_FEW_INIT_RETRIES=y
CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_OTG=y
# CONFIG_USB_OTG_PRODUCTLIST is not set
# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set
CONFIG_USB_OTG_FSM=y
CONFIG_USB_LEDS_TRIGGER_USBPORT=y
CONFIG_USB_AUTOSUSPEND_DELAY=2
CONFIG_USB_DEFAULT_AUTHORIZATION_MODE=1
CONFIG_USB_MON=y

#
# USB Host Controller Drivers
#
CONFIG_USB_C67X00_HCD=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DBGCAP=y
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_XHCI_PCI_RENESAS=y
CONFIG_USB_XHCI_PLATFORM=y
# CONFIG_USB_XHCI_SIDEBAND is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_EHCI_PCI=y
CONFIG_USB_EHCI_FSL=y
CONFIG_USB_EHCI_HCD_PLATFORM=y
CONFIG_USB_OXU210HP_HCD=y
CONFIG_USB_ISP116X_HCD=y
CONFIG_USB_MAX3421_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PCI=y
# CONFIG_USB_OHCI_HCD_SSB is not set
CONFIG_USB_OHCI_HCD_PLATFORM=y
CONFIG_USB_UHCI_HCD=y
CONFIG_USB_SL811_HCD=y
CONFIG_USB_SL811_HCD_ISO=y
CONFIG_USB_SL811_CS=y
CONFIG_USB_R8A66597_HCD=y
CONFIG_USB_HCD_BCMA=y
CONFIG_USB_HCD_SSB=y
# CONFIG_USB_HCD_TEST_MODE is not set

#
# USB Device Class drivers
#
CONFIG_USB_ACM=y
CONFIG_USB_PRINTER=y
CONFIG_USB_WDM=y
CONFIG_USB_TMC=y

#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_REALTEK=y
CONFIG_REALTEK_AUTOPM=y
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
CONFIG_USB_STORAGE_ALAUDA=y
CONFIG_USB_STORAGE_ONETOUCH=y
CONFIG_USB_STORAGE_KARMA=y
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_STORAGE_ENE_UB6250=y
CONFIG_USB_UAS=y

#
# USB Imaging devices
#
CONFIG_USB_MDC800=y
CONFIG_USB_MICROTEK=y
CONFIG_USBIP_CORE=y
CONFIG_USBIP_VHCI_HCD=y
CONFIG_USBIP_VHCI_HC_PORTS=8
CONFIG_USBIP_VHCI_NR_HCS=16
CONFIG_USBIP_HOST=y
CONFIG_USBIP_VUDC=y
# CONFIG_USBIP_DEBUG is not set

#
# USB dual-mode controller drivers
#
CONFIG_USB_CDNS_SUPPORT=y
CONFIG_USB_CDNS3=y
CONFIG_USB_CDNS3_HOST=y
CONFIG_USB_CDNS3_GADGET=y

#
# Platform glue driver support
#
CONFIG_USB_CDNS3_PCI_WRAP=y
CONFIG_USB_CDNSP_PCI=y
CONFIG_USB_MUSB_HDRC=y
# CONFIG_USB_MUSB_HOST is not set
# CONFIG_USB_MUSB_GADGET is not set
CONFIG_USB_MUSB_DUAL_ROLE=y

#
# Platform Glue Layer
#

#
# MUSB DMA mode
#
CONFIG_MUSB_PIO_ONLY=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_ULPI=y
# CONFIG_USB_DWC3_HOST is not set
CONFIG_USB_DWC3_GADGET=y
# CONFIG_USB_DWC3_DUAL_ROLE is not set

#
# Platform Glue Driver Support
#
CONFIG_USB_DWC3_PCI=y
CONFIG_USB_DWC3_HAPS=y
CONFIG_USB_DWC3_OF_SIMPLE=y
CONFIG_USB_DWC3_GENERIC_PLAT=y
# CONFIG_USB_DWC3_GOOGLE is not set
CONFIG_USB_DWC2=y
CONFIG_USB_DWC2_HOST=y

#
# Gadget/Dual-role mode requires USB Gadget support to be enabled
#
# CONFIG_USB_DWC2_PERIPHERAL is not set
# CONFIG_USB_DWC2_DUAL_ROLE is not set
CONFIG_USB_DWC2_PCI=y
# CONFIG_USB_DWC2_DEBUG is not set
# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_USB_CHIPIDEA_PCI=y
CONFIG_USB_CHIPIDEA_MSM=y
CONFIG_USB_CHIPIDEA_NPCM=y
# CONFIG_USB_CHIPIDEA_IMX is not set
CONFIG_USB_CHIPIDEA_GENERIC=y
# CONFIG_USB_CHIPIDEA_TEGRA is not set
CONFIG_USB_ISP1760=y
CONFIG_USB_ISP1760_HCD=y
CONFIG_USB_ISP1761_UDC=y
# CONFIG_USB_ISP1760_HOST_ROLE is not set
# CONFIG_USB_ISP1760_GADGET_ROLE is not set
CONFIG_USB_ISP1760_DUAL_ROLE=y

#
# USB port drivers
#
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_CONSOLE=y
CONFIG_USB_SERIAL_GENERIC=y
CONFIG_USB_SERIAL_SIMPLE=y
CONFIG_USB_SERIAL_AIRCABLE=y
CONFIG_USB_SERIAL_ARK3116=y
CONFIG_USB_SERIAL_BELKIN=y
CONFIG_USB_SERIAL_CH341=y
CONFIG_USB_SERIAL_WHITEHEAT=y
CONFIG_USB_SERIAL_DIGI_ACCELEPORT=y
CONFIG_USB_SERIAL_CP210X=y
CONFIG_USB_SERIAL_CYPRESS_M8=y
CONFIG_USB_SERIAL_EMPEG=y
CONFIG_USB_SERIAL_FTDI_SIO=y
CONFIG_USB_SERIAL_VISOR=y
CONFIG_USB_SERIAL_IPAQ=y
CONFIG_USB_SERIAL_IR=y
CONFIG_USB_SERIAL_EDGEPORT=y
CONFIG_USB_SERIAL_EDGEPORT_TI=y
CONFIG_USB_SERIAL_F81232=y
CONFIG_USB_SERIAL_F8153X=y
CONFIG_USB_SERIAL_GARMIN=y
CONFIG_USB_SERIAL_IPW=y
CONFIG_USB_SERIAL_IUU=y
CONFIG_USB_SERIAL_KEYSPAN_PDA=y
CONFIG_USB_SERIAL_KEYSPAN=y
CONFIG_USB_SERIAL_KLSI=y
CONFIG_USB_SERIAL_KOBIL_SCT=y
CONFIG_USB_SERIAL_MCT_U232=y
CONFIG_USB_SERIAL_METRO=y
CONFIG_USB_SERIAL_MOS7720=y
CONFIG_USB_SERIAL_MOS7715_PARPORT=y
CONFIG_USB_SERIAL_MOS7840=y
CONFIG_USB_SERIAL_MXUPORT=y
CONFIG_USB_SERIAL_NAVMAN=y
CONFIG_USB_SERIAL_PL2303=y
CONFIG_USB_SERIAL_OTI6858=y
CONFIG_USB_SERIAL_QCAUX=y
CONFIG_USB_SERIAL_QUALCOMM=y
CONFIG_USB_SERIAL_SPCP8X5=y
CONFIG_USB_SERIAL_SAFE=y
# CONFIG_USB_SERIAL_SAFE_PADDED is not set
CONFIG_USB_SERIAL_SIERRAWIRELESS=y
CONFIG_USB_SERIAL_SYMBOL=y
CONFIG_USB_SERIAL_TI=y
CONFIG_USB_SERIAL_CYBERJACK=y
CONFIG_USB_SERIAL_WWAN=y
CONFIG_USB_SERIAL_OPTION=y
CONFIG_USB_SERIAL_OMNINET=y
CONFIG_USB_SERIAL_OPTICON=y
CONFIG_USB_SERIAL_XSENS_MT=y
CONFIG_USB_SERIAL_WISHBONE=y
CONFIG_USB_SERIAL_SSU100=y
CONFIG_USB_SERIAL_QT2=y
CONFIG_USB_SERIAL_UPD78F0730=y
CONFIG_USB_SERIAL_XR=y
CONFIG_USB_SERIAL_DEBUG=y

#
# USB Miscellaneous drivers
#
CONFIG_USB_USS720=y
CONFIG_USB_EMI62=y
CONFIG_USB_EMI26=y
CONFIG_USB_ADUTUX=y
CONFIG_USB_SEVSEG=y
CONFIG_USB_LEGOTOWER=y
CONFIG_USB_LCD=y
CONFIG_USB_CYPRESS_CY7C63=y
CONFIG_USB_CYTHERM=y
CONFIG_USB_IDMOUSE=y
CONFIG_USB_APPLEDISPLAY=y
CONFIG_APPLE_MFI_FASTCHARGE=y
CONFIG_USB_LJCA=y
# CONFIG_USB_USBIO is not set
CONFIG_USB_SISUSBVGA=y
CONFIG_USB_LD=y
CONFIG_USB_TRANCEVIBRATOR=y
CONFIG_USB_IOWARRIOR=y
CONFIG_USB_TEST=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_USB_ISIGHTFW=y
CONFIG_USB_YUREX=y
CONFIG_USB_EZUSB_FX2=y
CONFIG_USB_HUB_USB251XB=y
CONFIG_USB_HSIC_USB3503=y
CONFIG_USB_HSIC_USB4604=y
CONFIG_USB_LINK_LAYER_TEST=y
CONFIG_USB_CHAOSKEY=y
# CONFIG_USB_ONBOARD_DEV is not set
CONFIG_USB_ATM=y
CONFIG_USB_SPEEDTOUCH=y
CONFIG_USB_CXACRU=y
CONFIG_USB_UEAGLEATM=y
CONFIG_USB_XUSBATM=y

#
# USB Physical Layer drivers
#
CONFIG_USB_PHY=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_TAHVO_USB=y
CONFIG_TAHVO_USB_HOST_BY_DEFAULT=y
CONFIG_USB_ISP1301=y
# end of USB Physical Layer drivers

CONFIG_USB_GADGET=y
# CONFIG_USB_GADGET_DEBUG is not set
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
CONFIG_U_SERIAL_CONSOLE=y

#
# USB Peripheral Controller
#
CONFIG_USB_GR_UDC=y
CONFIG_USB_R8A66597=y
CONFIG_USB_PXA27X=y
CONFIG_USB_SNP_CORE=y
# CONFIG_USB_SNP_UDC_PLAT is not set
# CONFIG_USB_M66592 is not set
CONFIG_USB_BDC_UDC=y
CONFIG_USB_AMD5536UDC=y
CONFIG_USB_NET2280=y
CONFIG_USB_GOKU=y
CONFIG_USB_EG20T=y
# CONFIG_USB_GADGET_XILINX is not set
CONFIG_USB_MAX3420_UDC=y
CONFIG_USB_CDNS2_UDC=y
CONFIG_USB_DUMMY_HCD=y
# end of USB Peripheral Controller

CONFIG_USB_LIBCOMPOSITE=y
CONFIG_USB_F_ACM=y
CONFIG_USB_F_SS_LB=y
CONFIG_USB_U_SERIAL=y
CONFIG_USB_U_ETHER=y
CONFIG_USB_U_AUDIO=y
CONFIG_USB_F_SERIAL=y
CONFIG_USB_F_OBEX=y
CONFIG_USB_F_NCM=y
CONFIG_USB_F_ECM=y
CONFIG_USB_F_PHONET=y
CONFIG_USB_F_EEM=y
CONFIG_USB_F_SUBSET=y
CONFIG_USB_F_RNDIS=y
CONFIG_USB_F_MASS_STORAGE=y
CONFIG_USB_F_FS=y
CONFIG_USB_F_UAC1=y
CONFIG_USB_F_UAC1_LEGACY=y
CONFIG_USB_F_UAC2=y
CONFIG_USB_F_UVC=y
CONFIG_USB_F_MIDI=y
CONFIG_USB_F_MIDI2=y
CONFIG_USB_F_HID=y
CONFIG_USB_F_PRINTER=y
CONFIG_USB_F_TCM=y
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_SERIAL=y
CONFIG_USB_CONFIGFS_ACM=y
CONFIG_USB_CONFIGFS_OBEX=y
CONFIG_USB_CONFIGFS_NCM=y
CONFIG_USB_CONFIGFS_ECM=y
CONFIG_USB_CONFIGFS_ECM_SUBSET=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_EEM=y
CONFIG_USB_CONFIGFS_PHONET=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_LB_SS=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_UAC1=y
CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_MIDI=y
CONFIG_USB_CONFIGFS_F_MIDI2=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_UVC=y
CONFIG_USB_CONFIGFS_F_PRINTER=y
CONFIG_USB_CONFIGFS_F_TCM=y

#
# USB Gadget precomposed configurations
#
# CONFIG_USB_ZERO is not set
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_ETH is not set
# CONFIG_USB_G_NCM is not set
CONFIG_USB_GADGETFS=y
# CONFIG_USB_FUNCTIONFS is not set
# CONFIG_USB_MASS_STORAGE is not set
# CONFIG_USB_GADGET_TARGET is not set
# CONFIG_USB_G_SERIAL is not set
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
# CONFIG_USB_G_NOKIA is not set
# CONFIG_USB_G_ACM_MS is not set
# CONFIG_USB_G_MULTI is not set
# CONFIG_USB_G_HID is not set
# CONFIG_USB_G_DBGP is not set
# CONFIG_USB_G_WEBCAM is not set
CONFIG_USB_RAW_GADGET=y
# end of USB Gadget precomposed configurations

CONFIG_TYPEC=y
CONFIG_TYPEC_TCPM=y
CONFIG_TYPEC_TCPCI=y
CONFIG_TYPEC_RT1711H=y
CONFIG_TYPEC_MT6360=y
CONFIG_TYPEC_TCPCI_MT6370=y
CONFIG_TYPEC_TCPCI_MAXIM=y
CONFIG_TYPEC_FUSB302=y
CONFIG_TYPEC_WCOVE=y
CONFIG_TYPEC_UCSI=y
CONFIG_UCSI_CCG=y
CONFIG_UCSI_ACPI=y
CONFIG_UCSI_STM32G0=y
CONFIG_TYPEC_TPS6598X=y
CONFIG_TYPEC_ANX7411=y
CONFIG_TYPEC_RT1719=y
CONFIG_TYPEC_HD3SS3220=y
CONFIG_TYPEC_STUSB160X=y
CONFIG_TYPEC_WUSB3801=y

#
# USB Type-C Multiplexer/DeMultiplexer Switch support
#
CONFIG_TYPEC_MUX_FSA4480=y
CONFIG_TYPEC_MUX_GPIO_SBU=y
CONFIG_TYPEC_MUX_PI3USB30532=y
CONFIG_TYPEC_MUX_INTEL_PMC=y
# CONFIG_TYPEC_MUX_IT5205 is not set
CONFIG_TYPEC_MUX_NB7VPQ904M=y
# CONFIG_TYPEC_MUX_PS883X is not set
CONFIG_TYPEC_MUX_PTN36502=y
# CONFIG_TYPEC_MUX_TUSB1046 is not set
CONFIG_TYPEC_MUX_WCD939X_USBSS=y
# end of USB Type-C Multiplexer/DeMultiplexer Switch support

#
# USB Type-C Alternate Mode drivers
#
CONFIG_TYPEC_DP_ALTMODE=y
CONFIG_TYPEC_NVIDIA_ALTMODE=y
# CONFIG_TYPEC_TBT_ALTMODE is not set
# end of USB Type-C Alternate Mode drivers

CONFIG_USB_ROLE_SWITCH=y
CONFIG_USB_ROLES_INTEL_XHCI=y
CONFIG_MMC=y
# CONFIG_PWRSEQ_EMMC is not set
# CONFIG_PWRSEQ_SD8787 is not set
# CONFIG_PWRSEQ_SIMPLE is not set
# CONFIG_MMC_BLOCK is not set
# CONFIG_SDIO_UART is not set
# CONFIG_MMC_TEST is not set
# CONFIG_MMC_CRYPTO is not set

#
# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_SDHCI is not set
# CONFIG_MMC_WBSD is not set
# CONFIG_MMC_TIFM_SD is not set
# CONFIG_MMC_SPI is not set
# CONFIG_MMC_SDRICOH_CS is not set
# CONFIG_MMC_CB710 is not set
# CONFIG_MMC_VIA_SDMMC is not set
CONFIG_MMC_VUB300=y
CONFIG_MMC_USHC=y
# CONFIG_MMC_USDHI6ROL0 is not set
CONFIG_MMC_REALTEK_USB=y
# CONFIG_MMC_CQHCI is not set
# CONFIG_MMC_HSQ is not set
# CONFIG_MMC_TOSHIBA_PCI is not set
# CONFIG_MMC_MTK is not set
# CONFIG_SCSI_UFSHCD is not set
CONFIG_MEMSTICK=y
# CONFIG_MEMSTICK_DEBUG is not set

#
# MemoryStick drivers
#
# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
# CONFIG_MSPRO_BLOCK is not set
# CONFIG_MS_BLOCK is not set

#
# MemoryStick Host Controller Drivers
#
# CONFIG_MEMSTICK_TIFM_MS is not set
# CONFIG_MEMSTICK_JMICRON_38X is not set
# CONFIG_MEMSTICK_R592 is not set
CONFIG_MEMSTICK_REALTEK_USB=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_CLASS_FLASH is not set
CONFIG_LEDS_CLASS_MULTICOLOR=y
# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set

#
# LED drivers
#
# CONFIG_LEDS_AN30259A is not set
# CONFIG_LEDS_APU is not set
# CONFIG_LEDS_OSRAM_AMS_AS3668 is not set
# CONFIG_LEDS_AW200XX is not set
# CONFIG_LEDS_AW2013 is not set
# CONFIG_LEDS_BCM6328 is not set
# CONFIG_LEDS_BCM6358 is not set
# CONFIG_LEDS_CHT_WCOVE is not set
# CONFIG_LEDS_CR0014114 is not set
# CONFIG_LEDS_EL15203000 is not set
# CONFIG_LEDS_LM3530 is not set
# CONFIG_LEDS_LM3532 is not set
# CONFIG_LEDS_LM3642 is not set
# CONFIG_LEDS_LM3692X is not set
# CONFIG_LEDS_PCA9532 is not set
# CONFIG_LEDS_GPIO is not set
# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_LP3952 is not set
# CONFIG_LEDS_LP50XX is not set
# CONFIG_LEDS_LP55XX_COMMON is not set
# CONFIG_LEDS_LP8860 is not set
# CONFIG_LEDS_LP8864 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_PCA963X is not set
# CONFIG_LEDS_PCA995X is not set
# CONFIG_LEDS_DAC124S085 is not set
# CONFIG_LEDS_REGULATOR is not set
# CONFIG_LEDS_BD2606MVV is not set
# CONFIG_LEDS_BD2802 is not set
# CONFIG_LEDS_INTEL_SS4200 is not set
# CONFIG_LEDS_LT3593 is not set
# CONFIG_LEDS_TCA6507 is not set
# CONFIG_LEDS_TLC591XX is not set
# CONFIG_LEDS_LM355x is not set
# CONFIG_LEDS_IS31FL319X is not set
# CONFIG_LEDS_IS31FL32XX is not set

#
# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM)
#
# CONFIG_LEDS_BLINKM is not set
# CONFIG_LEDS_SYSCON is not set
# CONFIG_LEDS_MLXCPLD is not set
# CONFIG_LEDS_MLXREG is not set
# CONFIG_LEDS_USER is not set
# CONFIG_LEDS_NIC78BX is not set
# CONFIG_LEDS_SPI_BYTE is not set
# CONFIG_LEDS_LM3697 is not set
# CONFIG_LEDS_ST1202 is not set
# CONFIG_LEDS_LGM is not set

#
# Flash and Torch LED drivers
#

#
# RGB LED drivers
#
# CONFIG_LEDS_GROUP_MULTICOLOR is not set
# CONFIG_LEDS_KTD202X is not set
# CONFIG_LEDS_LP5812 is not set
# CONFIG_LEDS_LP5860_CORE is not set
# CONFIG_LEDS_LP5860_SPI is not set
# CONFIG_LEDS_NCP5623 is not set
# CONFIG_LEDS_MT6370_RGB is not set

#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_TIMER is not set
# CONFIG_LEDS_TRIGGER_ONESHOT is not set
# CONFIG_LEDS_TRIGGER_DISK is not set
# CONFIG_LEDS_TRIGGER_MTD is not set
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_CPU is not set
# CONFIG_LEDS_TRIGGER_ACTIVITY is not set
# CONFIG_LEDS_TRIGGER_GPIO is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set

#
# iptables trigger is under Netfilter config (LED target)
#
# CONFIG_LEDS_TRIGGER_TRANSIENT is not set
# CONFIG_LEDS_TRIGGER_CAMERA is not set
# CONFIG_LEDS_TRIGGER_PANIC is not set
# CONFIG_LEDS_TRIGGER_NETDEV is not set
# CONFIG_LEDS_TRIGGER_PATTERN is not set
# CONFIG_LEDS_TRIGGER_TTY is not set
# CONFIG_LEDS_TRIGGER_INPUT_EVENTS is not set

#
# Simatic LED drivers
#
# CONFIG_ACCESSIBILITY is not set
CONFIG_INFINIBAND=y
CONFIG_INFINIBAND_USER_MAD=y
CONFIG_INFINIBAND_USER_ACCESS=y
CONFIG_INFINIBAND_USER_ACCESS_CORE=y
CONFIG_INFINIBAND_USER_MEM=y
CONFIG_INFINIBAND_ON_DEMAND_PAGING=y
CONFIG_INFINIBAND_ADDR_TRANS=y
CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y
CONFIG_INFINIBAND_VIRT_DMA=y
# CONFIG_INFINIBAND_EFA is not set
# CONFIG_INFINIBAND_ERDMA is not set
CONFIG_MLX4_INFINIBAND=y
# CONFIG_INFINIBAND_MTHCA is not set
# CONFIG_INFINIBAND_OCRDMA is not set
# CONFIG_INFINIBAND_USNIC is not set
# CONFIG_INFINIBAND_VMWARE_PVRDMA is not set
# CONFIG_INFINIBAND_RDMAVT is not set
CONFIG_RDMA_RXE=y
CONFIG_RDMA_SIW=y
CONFIG_INFINIBAND_IPOIB=y
CONFIG_INFINIBAND_IPOIB_CM=y
CONFIG_INFINIBAND_IPOIB_DEBUG=y
# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
CONFIG_INFINIBAND_SRP=y
# CONFIG_INFINIBAND_SRPT is not set
CONFIG_INFINIBAND_ISER=y
CONFIG_INFINIBAND_RTRS=y
CONFIG_INFINIBAND_RTRS_CLIENT=y
# CONFIG_INFINIBAND_RTRS_SERVER is not set
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EDAC=y
# CONFIG_EDAC_DEBUG is not set
# CONFIG_EDAC_DECODE_MCE is not set
# CONFIG_EDAC_SCRUB is not set
# CONFIG_EDAC_ECS is not set
# CONFIG_EDAC_MEM_REPAIR is not set
# CONFIG_EDAC_E752X is not set
# CONFIG_EDAC_I82975X is not set
# CONFIG_EDAC_I3000 is not set
# CONFIG_EDAC_I3200 is not set
# CONFIG_EDAC_IE31200 is not set
# CONFIG_EDAC_X38 is not set
# CONFIG_EDAC_I5400 is not set
# CONFIG_EDAC_I7CORE is not set
# CONFIG_EDAC_I5100 is not set
# CONFIG_EDAC_I7300 is not set
# CONFIG_EDAC_SBRIDGE is not set
# CONFIG_EDAC_SKX is not set
# CONFIG_EDAC_I10NM is not set
# CONFIG_EDAC_IMH is not set
# CONFIG_EDAC_PND2 is not set
# CONFIG_EDAC_IGEN6 is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_MC146818_LIB=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
CONFIG_RTC_SYSTOHC=y
CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set
# CONFIG_RTC_NVMEM is not set

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set

#
# I2C RTC drivers
#
# CONFIG_RTC_DRV_ABB5ZES3 is not set
# CONFIG_RTC_DRV_ABEOZ9 is not set
# CONFIG_RTC_DRV_ABX80X is not set
# CONFIG_RTC_DRV_DS1307 is not set
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_HYM8563 is not set
# CONFIG_RTC_DRV_MAX6900 is not set
# CONFIG_RTC_DRV_MAX31335 is not set
# CONFIG_RTC_DRV_NCT3018Y is not set
# CONFIG_RTC_DRV_RS5C372 is not set
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_ISL12022 is not set
# CONFIG_RTC_DRV_ISL12026 is not set
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF8523 is not set
# CONFIG_RTC_DRV_PCF85363 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_BQ32K is not set
# CONFIG_RTC_DRV_TWL4030 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8010 is not set
# CONFIG_RTC_DRV_RX8111 is not set
# CONFIG_RTC_DRV_RX8581 is not set
# CONFIG_RTC_DRV_RX8025 is not set
# CONFIG_RTC_DRV_EM3027 is not set
# CONFIG_RTC_DRV_RV3028 is not set
# CONFIG_RTC_DRV_RV3032 is not set
# CONFIG_RTC_DRV_RV8803 is not set
# CONFIG_RTC_DRV_SD2405AL is not set
# CONFIG_RTC_DRV_SD3078 is not set

#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T93 is not set
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1302 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1343 is not set
# CONFIG_RTC_DRV_DS1347 is not set
# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6916 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RX4581 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_PCF2123 is not set
# CONFIG_RTC_DRV_MCP795 is not set
CONFIG_RTC_I2C_AND_SPI=y

#
# SPI and I2C RTC drivers
#
# CONFIG_RTC_DRV_DS3232 is not set
# CONFIG_RTC_DRV_PCF2127 is not set
# CONFIG_RTC_DRV_PCF85063 is not set
# CONFIG_RTC_DRV_RV3029C2 is not set
# CONFIG_RTC_DRV_RX6110 is not set

#
# Platform RTC drivers
#
CONFIG_RTC_DRV_CMOS=y
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1685_FAMILY is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_DS2404 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_MSM6242 is not set
# CONFIG_RTC_DRV_RP5C01 is not set
# CONFIG_RTC_DRV_ZYNQMP is not set

#
# on-CPU RTC drivers
#
# CONFIG_RTC_DRV_CADENCE is not set
# CONFIG_RTC_DRV_FTRTC010 is not set
# CONFIG_RTC_DRV_R7301 is not set
# CONFIG_RTC_DRV_GOLDFISH is not set

#
# HID Sensor RTC drivers
#
CONFIG_RTC_DRV_HID_SENSOR_TIME=y
CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set

#
# DMA Devices
#
CONFIG_DMA_ENGINE=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DMA_ACPI=y
CONFIG_DMA_OF=y
# CONFIG_ALTERA_MSGDMA is not set
# CONFIG_DW_AXI_DMAC is not set
# CONFIG_FSL_EDMA is not set
CONFIG_INTEL_IDMA64=y
# CONFIG_INTEL_IDXD is not set
# CONFIG_INTEL_IDXD_COMPAT is not set
CONFIG_INTEL_IOATDMA=y
# CONFIG_PLX_DMA is not set
# CONFIG_SWITCHTEC_DMA is not set
# CONFIG_XILINX_DMA is not set
# CONFIG_XILINX_XDMA is not set
# CONFIG_XILINX_ZYNQMP_DPDMA is not set
# CONFIG_AMD_PTDMA is not set
# CONFIG_AMD_QDMA is not set
# CONFIG_QCOM_HIDMA_MGMT is not set
# CONFIG_QCOM_HIDMA is not set
CONFIG_DW_DMAC_CORE=y
# CONFIG_DW_DMAC is not set
# CONFIG_DW_DMAC_PCI is not set
# CONFIG_DW_EDMA is not set
CONFIG_HSU_DMA=y
# CONFIG_SF_PDMA is not set
# CONFIG_INTEL_LDMA is not set

#
# DMA Clients
#
CONFIG_ASYNC_TX_DMA=y
# CONFIG_DMATEST is not set
CONFIG_DMA_ENGINE_RAID=y

#
# DMABUF options
#
CONFIG_SYNC_FILE=y
CONFIG_SW_SYNC=y
CONFIG_UDMABUF=y
# CONFIG_DMABUF_DEBUG is not set
CONFIG_DMABUF_HEAPS=y
CONFIG_DMABUF_HEAPS_SYSTEM=y
# CONFIG_DMABUF_HEAPS_SYSTEM_CC_SHARED is not set
CONFIG_DMABUF_HEAPS_CMA=y
# end of DMABUF options

CONFIG_DCA=y
# CONFIG_UIO is not set
CONFIG_VFIO=y
CONFIG_VFIO_DEVICE_CDEV=y
# CONFIG_VFIO_GROUP is not set
CONFIG_VFIO_VIRQFD=y
# CONFIG_VFIO_DEBUGFS is not set

#
# VFIO support for PCI devices
#
CONFIG_VFIO_PCI_CORE=y
CONFIG_VFIO_PCI_INTX=y
CONFIG_VFIO_PCI=y
# CONFIG_VFIO_PCI_VGA is not set
# CONFIG_VFIO_PCI_IGD is not set
# CONFIG_VIRTIO_VFIO_PCI is not set
# end of VFIO support for PCI devices

CONFIG_IRQ_BYPASS_MANAGER=y
# CONFIG_VIRT_DRIVERS is not set
CONFIG_VIRTIO_ANCHOR=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI_LIB=y
CONFIG_VIRTIO_PCI_LIB_LEGACY=y
CONFIG_VIRTIO_MENU=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_PCI_ADMIN_LEGACY=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_VDPA=y
CONFIG_VIRTIO_PMEM=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_MEM=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_VIRTIO_DMA_SHARED_BUFFER=y
# CONFIG_VIRTIO_DEBUG is not set
# CONFIG_VIRTIO_RTC is not set
CONFIG_VDPA=y
CONFIG_VDPA_SIM=y
CONFIG_VDPA_SIM_NET=y
CONFIG_VDPA_SIM_BLOCK=y
# CONFIG_VDPA_USER is not set
# CONFIG_IFCVF is not set
# CONFIG_MLX5_VDPA_STEERING_DEBUG is not set
CONFIG_VP_VDPA=y
# CONFIG_ALIBABA_ENI_VDPA is not set
# CONFIG_SNET_VDPA is not set
# CONFIG_OCTEONEP_VDPA is not set
CONFIG_VHOST_IOTLB=y
CONFIG_VHOST_RING=y
CONFIG_VHOST_TASK=y
CONFIG_VHOST=y
CONFIG_VHOST_MENU=y
CONFIG_VHOST_NET=y
# CONFIG_VHOST_SCSI is not set
CONFIG_VHOST_VSOCK=y
CONFIG_VHOST_VDPA=y
CONFIG_VHOST_CROSS_ENDIAN_LEGACY=y
CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL=y

#
# Microsoft Hyper-V guest support
#
# CONFIG_HYPERV is not set
# end of Microsoft Hyper-V guest support

CONFIG_GREYBUS=y
# CONFIG_GREYBUS_BEAGLEPLAY is not set
CONFIG_GREYBUS_ES2=y
CONFIG_COMEDI=y
# CONFIG_COMEDI_DEBUG is not set
CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB=2048
CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB=20480
CONFIG_COMEDI_MISC_DRIVERS=y
CONFIG_COMEDI_BOND=y
CONFIG_COMEDI_TEST=y
CONFIG_COMEDI_PARPORT=y
CONFIG_COMEDI_ISA_DRIVERS=y
CONFIG_COMEDI_PCL711=y
CONFIG_COMEDI_PCL724=y
CONFIG_COMEDI_PCL726=y
CONFIG_COMEDI_PCL730=y
CONFIG_COMEDI_PCL812=y
CONFIG_COMEDI_PCL816=y
CONFIG_COMEDI_PCL818=y
CONFIG_COMEDI_PCM3724=y
CONFIG_COMEDI_AMPLC_DIO200_ISA=y
CONFIG_COMEDI_AMPLC_PC236_ISA=y
CONFIG_COMEDI_AMPLC_PC263_ISA=y
CONFIG_COMEDI_RTI800=y
CONFIG_COMEDI_RTI802=y
CONFIG_COMEDI_DAC02=y
CONFIG_COMEDI_DAS16M1=y
CONFIG_COMEDI_DAS08_ISA=y
# CONFIG_COMEDI_DAS16 is not set
CONFIG_COMEDI_DAS800=y
CONFIG_COMEDI_DAS1800=y
CONFIG_COMEDI_DAS6402=y
CONFIG_COMEDI_DT2801=y
CONFIG_COMEDI_DT2811=y
CONFIG_COMEDI_DT2814=y
CONFIG_COMEDI_DT2815=y
CONFIG_COMEDI_DT2817=y
CONFIG_COMEDI_DT282X=y
CONFIG_COMEDI_DMM32AT=y
CONFIG_COMEDI_FL512=y
CONFIG_COMEDI_AIO_AIO12_8=y
CONFIG_COMEDI_AIO_IIRO_16=y
# CONFIG_COMEDI_II_PCI20KC is not set
CONFIG_COMEDI_C6XDIGIO=y
CONFIG_COMEDI_MPC624=y
CONFIG_COMEDI_ADQ12B=y
CONFIG_COMEDI_NI_AT_A2150=y
CONFIG_COMEDI_NI_AT_AO=y
# CONFIG_COMEDI_NI_ATMIO is not set
CONFIG_COMEDI_NI_ATMIO16D=y
CONFIG_COMEDI_NI_LABPC_ISA=y
CONFIG_COMEDI_PCMAD=y
CONFIG_COMEDI_PCMDA12=y
CONFIG_COMEDI_PCMMIO=y
CONFIG_COMEDI_PCMUIO=y
CONFIG_COMEDI_MULTIQ3=y
CONFIG_COMEDI_S526=y
CONFIG_COMEDI_PCI_DRIVERS=y
CONFIG_COMEDI_8255_PCI=y
# CONFIG_COMEDI_ADDI_APCI_1032 is not set
# CONFIG_COMEDI_ADDI_APCI_1500 is not set
# CONFIG_COMEDI_ADDI_APCI_1516 is not set
# CONFIG_COMEDI_ADDI_APCI_1564 is not set
# CONFIG_COMEDI_ADDI_APCI_16XX is not set
# CONFIG_COMEDI_ADDI_APCI_2032 is not set
# CONFIG_COMEDI_ADDI_APCI_2200 is not set
# CONFIG_COMEDI_ADDI_APCI_3120 is not set
# CONFIG_COMEDI_ADDI_APCI_3501 is not set
# CONFIG_COMEDI_ADDI_APCI_3XXX is not set
# CONFIG_COMEDI_ADL_PCI6208 is not set
# CONFIG_COMEDI_ADL_PCI7250 is not set
# CONFIG_COMEDI_ADL_PCI7X3X is not set
# CONFIG_COMEDI_ADL_PCI8164 is not set
# CONFIG_COMEDI_ADL_PCI9111 is not set
CONFIG_COMEDI_ADL_PCI9118=y
# CONFIG_COMEDI_ADV_PCI1710 is not set
# CONFIG_COMEDI_ADV_PCI1720 is not set
# CONFIG_COMEDI_ADV_PCI1723 is not set
# CONFIG_COMEDI_ADV_PCI1724 is not set
# CONFIG_COMEDI_ADV_PCI1760 is not set
# CONFIG_COMEDI_ADV_PCI_DIO is not set
# CONFIG_COMEDI_AMPLC_DIO200_PCI is not set
# CONFIG_COMEDI_AMPLC_PC236_PCI is not set
# CONFIG_COMEDI_AMPLC_PC263_PCI is not set
# CONFIG_COMEDI_AMPLC_PCI224 is not set
# CONFIG_COMEDI_AMPLC_PCI230 is not set
# CONFIG_COMEDI_CONTEC_PCI_DIO is not set
# CONFIG_COMEDI_DAS08_PCI is not set
# CONFIG_COMEDI_DT3000 is not set
# CONFIG_COMEDI_DYNA_PCI10XX is not set
# CONFIG_COMEDI_GSC_HPDI is not set
# CONFIG_COMEDI_MF6X4 is not set
# CONFIG_COMEDI_ICP_MULTI is not set
# CONFIG_COMEDI_DAQBOARD2000 is not set
# CONFIG_COMEDI_JR3_PCI is not set
# CONFIG_COMEDI_KE_COUNTER is not set
# CONFIG_COMEDI_CB_PCIDAS64 is not set
# CONFIG_COMEDI_CB_PCIDAS is not set
# CONFIG_COMEDI_CB_PCIDDA is not set
# CONFIG_COMEDI_CB_PCIMDAS is not set
# CONFIG_COMEDI_CB_PCIMDDA is not set
# CONFIG_COMEDI_ME4000 is not set
# CONFIG_COMEDI_ME_DAQ is not set
# CONFIG_COMEDI_NI_6527 is not set
# CONFIG_COMEDI_NI_65XX is not set
# CONFIG_COMEDI_NI_660X is not set
# CONFIG_COMEDI_NI_670X is not set
CONFIG_COMEDI_NI_LABPC_PCI=y
# CONFIG_COMEDI_NI_PCIDIO is not set
# CONFIG_COMEDI_NI_PCIMIO is not set
# CONFIG_COMEDI_RTD520 is not set
# CONFIG_COMEDI_S626 is not set
CONFIG_COMEDI_PCMCIA_DRIVERS=y
# CONFIG_COMEDI_CB_DAS16_CS is not set
# CONFIG_COMEDI_DAS08_CS is not set
CONFIG_COMEDI_NI_DAQ_700_CS=y
# CONFIG_COMEDI_NI_DAQ_DIO24_CS is not set
CONFIG_COMEDI_NI_LABPC_CS=y
# CONFIG_COMEDI_NI_MIO_CS is not set
# CONFIG_COMEDI_QUATECH_DAQP_CS is not set
CONFIG_COMEDI_USB_DRIVERS=y
CONFIG_COMEDI_DT9812=y
CONFIG_COMEDI_NI_USB6501=y
CONFIG_COMEDI_USBDUX=y
CONFIG_COMEDI_USBDUXFAST=y
CONFIG_COMEDI_USBDUXSIGMA=y
CONFIG_COMEDI_VMK80XX=y
CONFIG_COMEDI_8254=y
CONFIG_COMEDI_8255=y
CONFIG_COMEDI_8255_SA=y
CONFIG_COMEDI_KCOMEDILIB=y
CONFIG_COMEDI_AMPLC_DIO200=y
CONFIG_COMEDI_AMPLC_PC236=y
CONFIG_COMEDI_DAS08=y
CONFIG_COMEDI_ISADMA=y
CONFIG_COMEDI_NI_LABPC=y
CONFIG_COMEDI_NI_LABPC_ISADMA=y
# CONFIG_COMEDI_TESTS is not set
# CONFIG_GPIB is not set
CONFIG_STAGING=y
# CONFIG_RTL8723BS is not set

#
# IIO staging drivers
#

#
# Accelerometers
#
# CONFIG_ADIS16203 is not set
# end of Accelerometers

#
# Analog to digital converters
#
# CONFIG_AD7816 is not set
# end of Analog to digital converters

#
# Analog digital bi-direction converters
#
# CONFIG_ADT7316 is not set
# end of Analog digital bi-direction converters

#
# Direct Digital Synthesis
#
# CONFIG_AD9832 is not set
# CONFIG_AD9834 is not set
# end of Direct Digital Synthesis

#
# Network Analyzer, Impedance Converters
#
# CONFIG_AD5933 is not set
# end of Network Analyzer, Impedance Converters
# end of IIO staging drivers

# CONFIG_FB_SM750 is not set
# CONFIG_STAGING_MEDIA is not set
# CONFIG_FB_TFT is not set
# CONFIG_MOST_COMPONENTS is not set
# CONFIG_GREYBUS_AUDIO is not set
# CONFIG_GREYBUS_BOOTROM is not set
# CONFIG_GREYBUS_FIRMWARE is not set
CONFIG_GREYBUS_HID=y
# CONFIG_GREYBUS_LOG is not set
# CONFIG_GREYBUS_LOOPBACK is not set
# CONFIG_GREYBUS_POWER is not set
# CONFIG_GREYBUS_RAW is not set
# CONFIG_GREYBUS_VIBRATOR is not set
CONFIG_GREYBUS_BRIDGED_PHY=y
# CONFIG_GREYBUS_GPIO is not set
# CONFIG_GREYBUS_I2C is not set
# CONFIG_GREYBUS_SDIO is not set
# CONFIG_GREYBUS_SPI is not set
# CONFIG_GREYBUS_UART is not set
CONFIG_GREYBUS_USB=y
# CONFIG_XIL_AXIS_FIFO is not set
# CONFIG_VME_BUS is not set
# CONFIG_GOLDFISH is not set
# CONFIG_CHROME_PLATFORMS is not set
# CONFIG_MELLANOX_PLATFORM is not set
CONFIG_SURFACE_PLATFORMS=y
# CONFIG_SURFACE3_WMI is not set
# CONFIG_SURFACE_3_POWER_OPREGION is not set
# CONFIG_SURFACE_ACPI_NOTIFY is not set
# CONFIG_SURFACE_AGGREGATOR_CDEV is not set
# CONFIG_SURFACE_AGGREGATOR_HUB is not set
CONFIG_SURFACE_AGGREGATOR_REGISTRY=y
# CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH is not set
# CONFIG_SURFACE_DTX is not set
# CONFIG_SURFACE_GPE is not set
# CONFIG_SURFACE_HOTPLUG is not set
# CONFIG_SURFACE_PLATFORM_PROFILE is not set
# CONFIG_SURFACE_PRO3_BUTTON is not set
CONFIG_SURFACE_AGGREGATOR=y
CONFIG_SURFACE_AGGREGATOR_BUS=y
CONFIG_X86_PLATFORM_DEVICES=y
CONFIG_WMI_BMOF=y
# CONFIG_HUAWEI_WMI is not set
# CONFIG_X86_PLATFORM_DRIVERS_UNIWILL is not set
# CONFIG_MXM_WMI is not set
# CONFIG_NVIDIA_WMI_EC_BACKLIGHT is not set
# CONFIG_XIAOMI_WMI is not set
# CONFIG_REDMI_WMI is not set
# CONFIG_GIGABYTE_WMI is not set
# CONFIG_BITLAND_MIFS_WMI is not set
# CONFIG_ACERHDF is not set
# CONFIG_ACER_WIRELESS is not set
# CONFIG_ACER_WMI is not set

#
# AMD HSMP Driver
#
# CONFIG_AMD_HSMP_ACPI is not set
# CONFIG_AMD_HSMP_PLAT is not set
# end of AMD HSMP Driver

# CONFIG_AMD_PMC is not set
# CONFIG_AMD_HFI is not set
# CONFIG_AMD_3D_VCACHE is not set
# CONFIG_AMD_WBRF is not set
# CONFIG_AMD_ISP_PLATFORM is not set
# CONFIG_ADV_SWBUTTON is not set
# CONFIG_APPLE_GMUX is not set
# CONFIG_ASUS_LAPTOP is not set
# CONFIG_ASUS_WIRELESS is not set
# CONFIG_ASUS_ARMOURY is not set
CONFIG_ASUS_WMI=y
# CONFIG_ASUS_WMI_DEPRECATED_ATTRS is not set
# CONFIG_ASUS_NB_WMI is not set
CONFIG_ASUS_TF103C_DOCK=y
# CONFIG_AYANEO_EC is not set
CONFIG_EEEPC_LAPTOP=y
# CONFIG_EEEPC_WMI is not set
# CONFIG_X86_PLATFORM_DRIVERS_DELL is not set
# CONFIG_AMILO_RFKILL is not set
# CONFIG_FUJITSU_LAPTOP is not set
# CONFIG_FUJITSU_TABLET is not set
# CONFIG_GPD_POCKET_FAN is not set
# CONFIG_X86_PLATFORM_DRIVERS_HP is not set
# CONFIG_WIRELESS_HOTKEY is not set
# CONFIG_IBM_RTL is not set
# CONFIG_SENSORS_HDAPS is not set
# CONFIG_INTEL_ATOMISP2_PM is not set
# CONFIG_INTEL_IFS is not set
# CONFIG_INTEL_SAR_INT1092 is not set
# CONFIG_INTEL_SKL_INT3472 is not set

#
# Intel Speed Select Technology interface support
#
# CONFIG_INTEL_SPEED_SELECT_INTERFACE is not set
# end of Intel Speed Select Technology interface support

# CONFIG_INTEL_WMI_SBL_FW_UPDATE is not set
# CONFIG_INTEL_WMI_THUNDERBOLT is not set

#
# Intel Uncore Frequency Control
#
# CONFIG_INTEL_UNCORE_FREQ_CONTROL is not set
# end of Intel Uncore Frequency Control

# CONFIG_INTEL_HID_EVENT is not set
# CONFIG_INTEL_VBTN is not set
# CONFIG_INTEL_EHL_PSE_IO is not set
# CONFIG_INTEL_INT0002_VGPIO is not set
# CONFIG_INTEL_OAKTRAIL is not set
# CONFIG_INTEL_BXTWC_PMIC_TMU is not set
CONFIG_INTEL_CHTWC_INT33FE=y
CONFIG_INTEL_ISHTP_ECLITE=y
# CONFIG_INTEL_PUNIT_IPC is not set
# CONFIG_INTEL_RST is not set
# CONFIG_INTEL_SMARTCONNECT is not set
# CONFIG_INTEL_TURBO_MAX_3 is not set
# CONFIG_INTEL_VSEC is not set
# CONFIG_IDEAPAD_LAPTOP is not set
# CONFIG_LENOVO_WMI_HOTKEY_UTILITIES is not set
# CONFIG_LENOVO_WMI_CAMERA is not set
# CONFIG_THINKPAD_ACPI is not set
# CONFIG_THINKPAD_LMI is not set
# CONFIG_YOGABOOK is not set
# CONFIG_YT2_1380 is not set
# CONFIG_LENOVO_WMI_GAMEZONE is not set
# CONFIG_LENOVO_WMI_TUNING is not set
# CONFIG_ACPI_QUICKSTART is not set
# CONFIG_MEEGOPAD_ANX7428 is not set
# CONFIG_MSI_EC is not set
# CONFIG_MSI_LAPTOP is not set
# CONFIG_MSI_WMI is not set
# CONFIG_MSI_WMI_PLATFORM is not set
# CONFIG_PCENGINES_APU2 is not set
# CONFIG_PORTWELL_EC is not set
# CONFIG_BARCO_P50_GPIO is not set
# CONFIG_SAMSUNG_GALAXYBOOK is not set
# CONFIG_SAMSUNG_LAPTOP is not set
# CONFIG_SAMSUNG_Q10 is not set
# CONFIG_ACPI_TOSHIBA is not set
# CONFIG_TOSHIBA_BT_RFKILL is not set
# CONFIG_TOSHIBA_HAPS is not set
# CONFIG_TOSHIBA_WMI is not set
# CONFIG_ACPI_CMPC is not set
# CONFIG_COMPAL_LAPTOP is not set
# CONFIG_LG_LAPTOP is not set
# CONFIG_PANASONIC_LAPTOP is not set
# CONFIG_SONY_LAPTOP is not set
# CONFIG_SYSTEM76_ACPI is not set
# CONFIG_TOPSTAR_LAPTOP is not set
# CONFIG_SERIAL_MULTI_INSTANTIATE is not set
# CONFIG_INSPUR_PLATFORM_PROFILE is not set
# CONFIG_DASHARO_ACPI is not set
# CONFIG_INTEL_IPS is not set
CONFIG_INTEL_SCU_IPC=y
# CONFIG_INTEL_SCU_PCI is not set
# CONFIG_INTEL_SCU_PLATFORM is not set
# CONFIG_SIEMENS_SIMATIC_IPC is not set
# CONFIG_SILICOM_PLATFORM is not set
# CONFIG_WINMATE_FM07_KEYS is not set
# CONFIG_OXP_EC is not set
# CONFIG_TUXEDO_NB04_WMI_AB is not set
CONFIG_P2SB=y
CONFIG_ACPI_WMI=y
# CONFIG_ACPI_WMI_LEGACY_DEVICE_NAMES is not set
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_COMMON_CLK=y
# CONFIG_LMK04832 is not set
# CONFIG_COMMON_CLK_MAX9485 is not set
# CONFIG_COMMON_CLK_SI5341 is not set
# CONFIG_COMMON_CLK_SI5351 is not set
# CONFIG_COMMON_CLK_SI514 is not set
# CONFIG_COMMON_CLK_SI544 is not set
# CONFIG_COMMON_CLK_SI570 is not set
# CONFIG_COMMON_CLK_CDCE706 is not set
# CONFIG_COMMON_CLK_CDCE925 is not set
# CONFIG_COMMON_CLK_CS2000_CP is not set
# CONFIG_CLK_TWL is not set
# CONFIG_COMMON_CLK_AXI_CLKGEN is not set
# CONFIG_COMMON_CLK_RS9_PCIE is not set
# CONFIG_COMMON_CLK_SI521XX is not set
# CONFIG_COMMON_CLK_VC3 is not set
# CONFIG_COMMON_CLK_VC5 is not set
# CONFIG_COMMON_CLK_VC7 is not set
# CONFIG_COMMON_CLK_FIXED_MMIO is not set
# CONFIG_CLK_LGM_CGU is not set
# CONFIG_XILINX_VCU is not set
# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set
# CONFIG_HWSPINLOCK is not set

#
# Clock Source drivers
#
CONFIG_CLKEVT_I8253=y
CONFIG_I8253_LOCK=y
CONFIG_CLKBLD_I8253=y
# end of Clock Source drivers

CONFIG_MAILBOX=y
# CONFIG_PLATFORM_MHU is not set
CONFIG_PCC=y
# CONFIG_ALTERA_MBOX is not set
# CONFIG_MAILBOX_TEST is not set
CONFIG_IOMMU_IOVA=y
CONFIG_IOMMU_API=y
CONFIG_IOMMUFD_DRIVER=y
CONFIG_IOMMU_SUPPORT=y

#
# Generic IOMMU Pagetable Support
#
# end of Generic IOMMU Pagetable Support

# CONFIG_IOMMU_DEBUGFS is not set
# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set
CONFIG_IOMMU_DEFAULT_DMA_LAZY=y
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_OF_IOMMU=y
CONFIG_IOMMU_DMA=y
CONFIG_IOMMU_SVA=y
CONFIG_IOMMU_IOPF=y
CONFIG_AMD_IOMMU=y
# CONFIG_AMD_IOMMU_IOMMUFD is not set
CONFIG_DMAR_TABLE=y
CONFIG_INTEL_IOMMU=y
CONFIG_INTEL_IOMMU_SVM=y
CONFIG_INTEL_IOMMU_DEFAULT_ON=y
CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON=y
CONFIG_INTEL_IOMMU_PERF_EVENTS=y
CONFIG_IOMMUFD_DRIVER_CORE=y
CONFIG_IOMMUFD=y
CONFIG_IOMMUFD_TEST=y
CONFIG_IRQ_REMAP=y
# CONFIG_VIRTIO_IOMMU is not set
CONFIG_GENERIC_PT=y
# CONFIG_DEBUG_GENERIC_PT is not set
CONFIG_IOMMU_PT=y
CONFIG_IOMMU_PT_AMDV1=y
CONFIG_IOMMU_PT_VTDSS=y
# CONFIG_IOMMU_PT_RISCV64 is not set
CONFIG_IOMMU_PT_X86_64=y

#
# Remoteproc drivers
#
# CONFIG_REMOTEPROC is not set
# end of Remoteproc drivers

#
# Rpmsg drivers
#
# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
# CONFIG_RPMSG_VIRTIO is not set
# end of Rpmsg drivers

CONFIG_SOUNDWIRE=y

#
# SoundWire Devices
#
# CONFIG_SOUNDWIRE_AMD is not set
# CONFIG_SOUNDWIRE_INTEL is not set
# CONFIG_SOUNDWIRE_QCOM is not set

#
# SOC (System On Chip) specific Drivers
#

#
# Amlogic SoC drivers
#
# end of Amlogic SoC drivers

#
# Broadcom SoC drivers
#
# end of Broadcom SoC drivers

#
# NXP/Freescale QorIQ SoC drivers
#
# end of NXP/Freescale QorIQ SoC drivers

#
# fujitsu SoC drivers
#
# end of fujitsu SoC drivers

#
# i.MX SoC drivers
#
# end of i.MX SoC drivers

#
# Enable LiteX SoC Builder specific drivers
#
# CONFIG_LITEX_SOC_CONTROLLER is not set
# end of Enable LiteX SoC Builder specific drivers

# CONFIG_WPCM450_SOC is not set

#
# Qualcomm SoC drivers
#
CONFIG_QCOM_QMI_HELPERS=y
# end of Qualcomm SoC drivers

# CONFIG_SOC_TI is not set

#
# Xilinx SoC drivers
#
# end of Xilinx SoC drivers
# end of SOC (System On Chip) specific Drivers

#
# PM Domains
#

#
# Amlogic PM Domains
#
# end of Amlogic PM Domains

#
# Broadcom PM Domains
#
# end of Broadcom PM Domains

#
# i.MX PM Domains
#
# end of i.MX PM Domains

#
# Qualcomm PM Domains
#
# end of Qualcomm PM Domains
# end of PM Domains

# CONFIG_PM_DEVFREQ is not set
CONFIG_EXTCON=y

#
# Extcon Device Drivers
#
# CONFIG_EXTCON_ADC_JACK is not set
# CONFIG_EXTCON_FSA9480 is not set
# CONFIG_EXTCON_GPIO is not set
# CONFIG_EXTCON_INTEL_INT3496 is not set
CONFIG_EXTCON_INTEL_CHT_WC=y
# CONFIG_EXTCON_LC824206XA is not set
# CONFIG_EXTCON_MAX3355 is not set
# CONFIG_EXTCON_MAX14526 is not set
CONFIG_EXTCON_PTN5150=y
# CONFIG_EXTCON_RT8973A is not set
# CONFIG_EXTCON_SM5502 is not set
# CONFIG_EXTCON_USB_GPIO is not set
CONFIG_EXTCON_USBC_TUSB320=y
# CONFIG_MEMORY is not set
CONFIG_IIO=y
CONFIG_IIO_BUFFER=y
# CONFIG_IIO_BUFFER_CB is not set
# CONFIG_IIO_BUFFER_DMA is not set
# CONFIG_IIO_BUFFER_DMAENGINE is not set
# CONFIG_IIO_BUFFER_HW_CONSUMER is not set
CONFIG_IIO_KFIFO_BUF=y
CONFIG_IIO_TRIGGERED_BUFFER=y
# CONFIG_IIO_CONFIGFS is not set
CONFIG_IIO_TRIGGER=y
CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
# CONFIG_IIO_SW_DEVICE is not set
# CONFIG_IIO_SW_TRIGGER is not set
# CONFIG_IIO_TRIGGERED_EVENT is not set

#
# Accelerometers
#
# CONFIG_ADIS16201 is not set
# CONFIG_ADIS16209 is not set
# CONFIG_ADXL313_I2C is not set
# CONFIG_ADXL313_SPI is not set
# CONFIG_ADXL345_I2C is not set
# CONFIG_ADXL345_SPI is not set
# CONFIG_ADXL355_I2C is not set
# CONFIG_ADXL355_SPI is not set
# CONFIG_ADXL367_SPI is not set
# CONFIG_ADXL367_I2C is not set
# CONFIG_ADXL372_SPI is not set
# CONFIG_ADXL372_I2C is not set
# CONFIG_ADXL380_SPI is not set
# CONFIG_ADXL380_I2C is not set
# CONFIG_BMA180 is not set
# CONFIG_BMA220 is not set
# CONFIG_BMA400 is not set
# CONFIG_BMC150_ACCEL is not set
# CONFIG_BMI088_ACCEL is not set
# CONFIG_DA280 is not set
# CONFIG_DA311 is not set
# CONFIG_DMARD06 is not set
# CONFIG_DMARD09 is not set
# CONFIG_DMARD10 is not set
# CONFIG_FXLS8962AF_I2C is not set
# CONFIG_FXLS8962AF_SPI is not set
CONFIG_HID_SENSOR_ACCEL_3D=y
# CONFIG_IIO_ST_ACCEL_3AXIS is not set
# CONFIG_IIO_KX022A_SPI is not set
# CONFIG_IIO_KX022A_I2C is not set
# CONFIG_KXSD9 is not set
# CONFIG_KXCJK1013 is not set
# CONFIG_MC3230 is not set
# CONFIG_MMA7455_I2C is not set
# CONFIG_MMA7455_SPI is not set
# CONFIG_MMA7660 is not set
# CONFIG_MMA8452 is not set
# CONFIG_MMA9551 is not set
# CONFIG_MMA9553 is not set
# CONFIG_MSA311 is not set
# CONFIG_MXC4005 is not set
# CONFIG_MXC6255 is not set
# CONFIG_SCA3000 is not set
# CONFIG_SCA3300 is not set
# CONFIG_STK8312 is not set
# CONFIG_STK8BA50 is not set
# end of Accelerometers

#
# Analog to digital converters
#
# CONFIG_AD4000 is not set
# CONFIG_AD4080 is not set
# CONFIG_AD4130 is not set
# CONFIG_AD4134 is not set
# CONFIG_AD4170_4 is not set
# CONFIG_AD4691 is not set
# CONFIG_AD4695 is not set
# CONFIG_AD7091R5 is not set
# CONFIG_AD7091R8 is not set
# CONFIG_AD7124 is not set
# CONFIG_AD7173 is not set
# CONFIG_AD7191 is not set
# CONFIG_AD7192 is not set
# CONFIG_AD7266 is not set
# CONFIG_AD7280 is not set
# CONFIG_AD7291 is not set
# CONFIG_AD7292 is not set
# CONFIG_AD7298 is not set
# CONFIG_AD7380 is not set
# CONFIG_AD7476 is not set
# CONFIG_AD7606_IFACE_PARALLEL is not set
# CONFIG_AD7606_IFACE_SPI is not set
# CONFIG_AD7766 is not set
# CONFIG_AD7768_1 is not set
# CONFIG_AD7779 is not set
# CONFIG_AD7780 is not set
# CONFIG_AD7791 is not set
# CONFIG_AD7793 is not set
# CONFIG_AD7887 is not set
# CONFIG_AD7923 is not set
# CONFIG_AD7944 is not set
# CONFIG_AD7949 is not set
# CONFIG_AD799X is not set
# CONFIG_AD9467 is not set
# CONFIG_ADE9000 is not set
# CONFIG_CC10001_ADC is not set
CONFIG_DLN2_ADC=y
# CONFIG_ENVELOPE_DETECTOR is not set
# CONFIG_GEHC_PMC_ADC is not set
# CONFIG_HI8435 is not set
# CONFIG_HX711 is not set
# CONFIG_INA2XX_ADC is not set
# CONFIG_LTC2309 is not set
# CONFIG_LTC2471 is not set
# CONFIG_LTC2485 is not set
# CONFIG_LTC2496 is not set
# CONFIG_LTC2497 is not set
# CONFIG_MAX1027 is not set
# CONFIG_MAX11100 is not set
# CONFIG_MAX1118 is not set
# CONFIG_MAX11205 is not set
# CONFIG_MAX11410 is not set
# CONFIG_MAX1241 is not set
# CONFIG_MAX1363 is not set
# CONFIG_MAX14001 is not set
# CONFIG_MAX34408 is not set
# CONFIG_MAX9611 is not set
# CONFIG_MCP320X is not set
# CONFIG_MCP3422 is not set
# CONFIG_MCP3564 is not set
# CONFIG_MCP3911 is not set
# CONFIG_MEDIATEK_MT6360_ADC is not set
# CONFIG_MEDIATEK_MT6370_ADC is not set
# CONFIG_NAU7802 is not set
# CONFIG_NCT7201 is not set
# CONFIG_PAC1921 is not set
# CONFIG_PAC1934 is not set
# CONFIG_ROHM_BD79112 is not set
# CONFIG_ROHM_BD79124 is not set
# CONFIG_RICHTEK_RTQ6056 is not set
# CONFIG_SD_ADC_MODULATOR is not set
# CONFIG_TI_ADC081C is not set
# CONFIG_TI_ADC0832 is not set
# CONFIG_TI_ADC084S021 is not set
# CONFIG_TI_ADC108S102 is not set
# CONFIG_TI_ADC12138 is not set
# CONFIG_TI_ADC128S052 is not set
# CONFIG_TI_ADC161S626 is not set
# CONFIG_TI_ADS1015 is not set
# CONFIG_TI_ADS1018 is not set
# CONFIG_TI_ADS1100 is not set
# CONFIG_TI_ADS1119 is not set
# CONFIG_TI_ADS124S08 is not set
# CONFIG_TI_ADS1298 is not set
# CONFIG_TI_ADS131E08 is not set
# CONFIG_TI_ADS131M02 is not set
# CONFIG_TI_ADS7138 is not set
# CONFIG_TI_ADS7924 is not set
# CONFIG_TI_ADS7950 is not set
# CONFIG_TI_ADS8344 is not set
# CONFIG_TI_ADS8688 is not set
# CONFIG_TI_LMP92064 is not set
# CONFIG_TI_TLC4541 is not set
# CONFIG_TI_TSC2046 is not set
# CONFIG_TWL4030_MADC is not set
# CONFIG_TWL6030_GPADC is not set
# CONFIG_VF610_ADC is not set
CONFIG_VIPERBOARD_ADC=y
# CONFIG_XILINX_XADC is not set
# end of Analog to digital converters

#
# Analog to digital and digital to analog converters
#
# CONFIG_AD74115 is not set
# CONFIG_AD74413R is not set
# end of Analog to digital and digital to analog converters

#
# Analog Front Ends
#
# CONFIG_IIO_RESCALE is not set
# end of Analog Front Ends

#
# Amplifiers
#
# CONFIG_AD8366 is not set
# CONFIG_ADA4250 is not set
# CONFIG_ADL8113 is not set
# CONFIG_HMC425 is not set
# end of Amplifiers

#
# Capacitance to digital converters
#
# CONFIG_AD7150 is not set
# CONFIG_AD7746 is not set
# end of Capacitance to digital converters

#
# Chemical Sensors
#
# CONFIG_AOSONG_AGS02MA is not set
# CONFIG_ATLAS_PH_SENSOR is not set
# CONFIG_ATLAS_EZO_SENSOR is not set
# CONFIG_BME680 is not set
# CONFIG_CCS811 is not set
# CONFIG_ENS160 is not set
# CONFIG_IAQCORE is not set
# CONFIG_MHZ19B is not set
# CONFIG_PMS7003 is not set
# CONFIG_SCD30_CORE is not set
# CONFIG_SCD4X is not set
# CONFIG_SEN0322 is not set
# CONFIG_SENSIRION_SGP30 is not set
# CONFIG_SENSIRION_SGP40 is not set
# CONFIG_SPS30_I2C is not set
# CONFIG_SPS30_SERIAL is not set
# CONFIG_SENSEAIR_SUNRISE_CO2 is not set
# CONFIG_VZ89X is not set
# end of Chemical Sensors

#
# Hid Sensor IIO Common
#
CONFIG_HID_SENSOR_IIO_COMMON=y
CONFIG_HID_SENSOR_IIO_TRIGGER=y
# end of Hid Sensor IIO Common

#
# IIO SCMI Sensors
#
# end of IIO SCMI Sensors

#
# SSP Sensor Common
#
# CONFIG_IIO_SSP_SENSORHUB is not set
# end of SSP Sensor Common

#
# Digital to analog converters
#
# CONFIG_AD3530R is not set
# CONFIG_AD3552R_HS is not set
# CONFIG_AD3552R is not set
# CONFIG_AD5064 is not set
# CONFIG_AD5360 is not set
# CONFIG_AD5380 is not set
# CONFIG_AD5421 is not set
# CONFIG_AD5446_SPI is not set
# CONFIG_AD5446_I2C is not set
# CONFIG_AD5449 is not set
# CONFIG_AD5592R is not set
# CONFIG_AD5593R is not set
# CONFIG_AD5504 is not set
# CONFIG_AD5624R_SPI is not set
# CONFIG_AD5706R is not set
# CONFIG_AD9739A is not set
# CONFIG_LTC2688 is not set
# CONFIG_AD5686_SPI is not set
# CONFIG_AD5696_I2C is not set
# CONFIG_AD5755 is not set
# CONFIG_AD5758 is not set
# CONFIG_AD5761 is not set
# CONFIG_AD5764 is not set
# CONFIG_AD5766 is not set
# CONFIG_AD5770R is not set
# CONFIG_AD5791 is not set
# CONFIG_AD7293 is not set
# CONFIG_AD7303 is not set
# CONFIG_AD8460 is not set
# CONFIG_AD8801 is not set
# CONFIG_BD79703 is not set
# CONFIG_CIO_DAC is not set
# CONFIG_DPOT_DAC is not set
# CONFIG_DS4424 is not set
# CONFIG_LTC1660 is not set
# CONFIG_LTC2632 is not set
# CONFIG_LTC2664 is not set
# CONFIG_M62332 is not set
# CONFIG_MAX517 is not set
# CONFIG_MAX22007 is not set
# CONFIG_MAX5522 is not set
# CONFIG_MAX5821 is not set
# CONFIG_MCP4725 is not set
# CONFIG_MCP4728 is not set
# CONFIG_MCP47FEB02 is not set
# CONFIG_MCP4821 is not set
# CONFIG_MCP4922 is not set
# CONFIG_TI_DAC082S085 is not set
# CONFIG_TI_DAC5571 is not set
# CONFIG_TI_DAC7311 is not set
# CONFIG_TI_DAC7612 is not set
# CONFIG_VF610_DAC is not set
# end of Digital to analog converters

#
# IIO dummy driver
#
# end of IIO dummy driver

#
# Filters
#
# CONFIG_ADMV8818 is not set
# end of Filters

#
# Frequency Synthesizers DDS/PLL
#

#
# Clock Generator/Distribution
#
# CONFIG_AD9523 is not set
# end of Clock Generator/Distribution

#
# Phase-Locked Loop (PLL) frequency synthesizers
#
# CONFIG_ADF4350 is not set
# CONFIG_ADF4371 is not set
# CONFIG_ADF4377 is not set
# CONFIG_ADMFM2000 is not set
# CONFIG_ADMV1013 is not set
# CONFIG_ADMV1014 is not set
# CONFIG_ADMV4420 is not set
# CONFIG_ADRF6780 is not set
# end of Phase-Locked Loop (PLL) frequency synthesizers
# end of Frequency Synthesizers DDS/PLL

#
# Digital gyroscope sensors
#
# CONFIG_ADIS16080 is not set
# CONFIG_ADIS16130 is not set
# CONFIG_ADIS16136 is not set
# CONFIG_ADIS16260 is not set
# CONFIG_ADXRS290 is not set
# CONFIG_ADXRS450 is not set
# CONFIG_BMG160 is not set
# CONFIG_FXAS21002C is not set
CONFIG_HID_SENSOR_GYRO_3D=y
# CONFIG_MPU3050_I2C is not set
# CONFIG_IIO_ST_GYRO_3AXIS is not set
# CONFIG_ITG3200 is not set
# end of Digital gyroscope sensors

#
# Health Sensors
#

#
# Heart Rate Monitors
#
# CONFIG_AFE4403 is not set
# CONFIG_AFE4404 is not set
# CONFIG_MAX30100 is not set
# CONFIG_MAX30102 is not set
# end of Heart Rate Monitors
# end of Health Sensors

#
# Humidity sensors
#
# CONFIG_AM2315 is not set
# CONFIG_DHT11 is not set
# CONFIG_ENS210 is not set
# CONFIG_HDC100X is not set
# CONFIG_HDC2010 is not set
# CONFIG_HDC3020 is not set
CONFIG_HID_SENSOR_HUMIDITY=y
# CONFIG_HTS221 is not set
# CONFIG_HTU21 is not set
# CONFIG_SI7005 is not set
# CONFIG_SI7020 is not set
# end of Humidity sensors

#
# Inertial measurement units
#
# CONFIG_ADIS16400 is not set
# CONFIG_ADIS16460 is not set
# CONFIG_ADIS16475 is not set
# CONFIG_ADIS16480 is not set
# CONFIG_ADIS16550 is not set
# CONFIG_BMI160_I2C is not set
# CONFIG_BMI160_SPI is not set
# CONFIG_BMI270_I2C is not set
# CONFIG_BMI270_SPI is not set
# CONFIG_BMI323_I2C is not set
# CONFIG_BMI323_SPI is not set
# CONFIG_BOSCH_BNO055_SERIAL is not set
# CONFIG_BOSCH_BNO055_I2C is not set
# CONFIG_FXOS8700_I2C is not set
# CONFIG_FXOS8700_SPI is not set
# CONFIG_KMX61 is not set
# CONFIG_INV_ICM42600_I2C is not set
# CONFIG_INV_ICM42600_SPI is not set
# CONFIG_INV_ICM45600_I2C is not set
# CONFIG_INV_ICM45600_SPI is not set
# CONFIG_INV_MPU6050_I2C is not set
# CONFIG_INV_MPU6050_SPI is not set
# CONFIG_SMI240 is not set
# CONFIG_SMI330_I2C is not set
# CONFIG_SMI330_SPI is not set
# CONFIG_IIO_ST_LSM6DSX is not set
# CONFIG_IIO_ST_LSM9DS0 is not set
# end of Inertial measurement units

#
# Light sensors
#
# CONFIG_ACPI_ALS is not set
# CONFIG_ADJD_S311 is not set
# CONFIG_ADUX1020 is not set
# CONFIG_AL3000A is not set
# CONFIG_AL3010 is not set
# CONFIG_AL3320A is not set
# CONFIG_APDS9160 is not set
# CONFIG_APDS9300 is not set
# CONFIG_APDS9306 is not set
# CONFIG_APDS9960 is not set
# CONFIG_APDS9999 is not set
# CONFIG_AS73211 is not set
# CONFIG_BH1745 is not set
# CONFIG_BH1750 is not set
# CONFIG_BH1780 is not set
# CONFIG_CM32181 is not set
# CONFIG_CM3232 is not set
# CONFIG_CM3323 is not set
# CONFIG_CM3605 is not set
# CONFIG_CM36651 is not set
# CONFIG_GP2AP002 is not set
# CONFIG_GP2AP020A00F is not set
# CONFIG_SENSORS_ISL29018 is not set
# CONFIG_SENSORS_ISL29028 is not set
# CONFIG_ISL29125 is not set
# CONFIG_ISL76682 is not set
CONFIG_HID_SENSOR_ALS=y
CONFIG_HID_SENSOR_PROX=y
# CONFIG_JSA1212 is not set
# CONFIG_ROHM_BU27034 is not set
# CONFIG_RPR0521 is not set
# CONFIG_LTR390 is not set
# CONFIG_LTR501 is not set
# CONFIG_LTRF216A is not set
# CONFIG_LV0104CS is not set
# CONFIG_MAX44000 is not set
# CONFIG_MAX44009 is not set
# CONFIG_NOA1305 is not set
# CONFIG_OPT3001 is not set
# CONFIG_OPT4001 is not set
# CONFIG_OPT4060 is not set
# CONFIG_PA12203001 is not set
# CONFIG_SI1133 is not set
# CONFIG_SI1145 is not set
# CONFIG_STK3310 is not set
# CONFIG_ST_UVIS25 is not set
# CONFIG_TCS3414 is not set
# CONFIG_TCS3472 is not set
# CONFIG_SENSORS_TSL2563 is not set
# CONFIG_TSL2583 is not set
# CONFIG_TSL2591 is not set
# CONFIG_TSL2772 is not set
# CONFIG_TSL4531 is not set
# CONFIG_US5182D is not set
# CONFIG_VCNL4000 is not set
# CONFIG_VCNL4035 is not set
# CONFIG_VEML3235 is not set
# CONFIG_VEML3328 is not set
# CONFIG_VEML6030 is not set
# CONFIG_VEML6040 is not set
# CONFIG_VEML6046X00 is not set
# CONFIG_VEML6070 is not set
# CONFIG_VEML6075 is not set
# CONFIG_VL6180 is not set
# CONFIG_ZOPT2201 is not set
# end of Light sensors

#
# Magnetometer sensors
#
# CONFIG_AF8133J is not set
# CONFIG_AK8974 is not set
# CONFIG_AK8975 is not set
# CONFIG_AK09911 is not set
# CONFIG_ALS31300 is not set
# CONFIG_BMC150_MAGN_I2C is not set
# CONFIG_BMC150_MAGN_SPI is not set
# CONFIG_MAG3110 is not set
CONFIG_HID_SENSOR_MAGNETOMETER_3D=y
# CONFIG_MMC35240 is not set
# CONFIG_MMC5633 is not set
# CONFIG_MMC5983 is not set
# CONFIG_IIO_ST_MAGN_3AXIS is not set
# CONFIG_INFINEON_TLV493D is not set
# CONFIG_SENSORS_HMC5843_I2C is not set
# CONFIG_SENSORS_HMC5843_SPI is not set
# CONFIG_SENSORS_RM3100_I2C is not set
# CONFIG_SENSORS_RM3100_SPI is not set
# CONFIG_SI7210 is not set
# CONFIG_TI_TMAG5273 is not set
# CONFIG_YAMAHA_YAS530 is not set
# end of Magnetometer sensors

#
# Multiplexers
#
# CONFIG_IIO_MUX is not set
# end of Multiplexers

#
# Inclinometer sensors
#
CONFIG_HID_SENSOR_INCLINOMETER_3D=y
CONFIG_HID_SENSOR_DEVICE_ROTATION=y
# end of Inclinometer sensors

#
# Triggers - standalone
#
# CONFIG_IIO_SYSFS_TRIGGER is not set
# end of Triggers - standalone

#
# Linear and angular position sensors
#
CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE=y
# end of Linear and angular position sensors

#
# Digital potentiometers
#
# CONFIG_AD5110 is not set
# CONFIG_AD5272 is not set
# CONFIG_DS1803 is not set
# CONFIG_MAX5432 is not set
# CONFIG_MAX5481 is not set
# CONFIG_MAX5487 is not set
# CONFIG_MCP4018 is not set
# CONFIG_MCP4131 is not set
# CONFIG_MCP4531 is not set
# CONFIG_MCP41010 is not set
# CONFIG_TPL0102 is not set
# CONFIG_X9250 is not set
# end of Digital potentiometers

#
# Digital potentiostats
#
# CONFIG_LMP91000 is not set
# end of Digital potentiostats

#
# Pressure sensors
#
# CONFIG_ABP060MG is not set
# CONFIG_ABP2030PA_I2C is not set
# CONFIG_ABP2030PA_SPI is not set
# CONFIG_ROHM_BM1390 is not set
# CONFIG_BMP280 is not set
# CONFIG_DLHL60D is not set
# CONFIG_DPS310 is not set
CONFIG_HID_SENSOR_PRESS=y
# CONFIG_HP03 is not set
# CONFIG_HSC030PA is not set
# CONFIG_ICP10100 is not set
# CONFIG_MPL115_I2C is not set
# CONFIG_MPL115_SPI is not set
# CONFIG_MPL3115 is not set
# CONFIG_MPRLS0025PA_I2C is not set
# CONFIG_MPRLS0025PA_SPI is not set
# CONFIG_MS5611 is not set
# CONFIG_MS5637 is not set
# CONFIG_SDP500 is not set
# CONFIG_IIO_ST_PRESS is not set
# CONFIG_T5403 is not set
# CONFIG_HP206C is not set
# CONFIG_ZPA2326 is not set
# CONFIG_ADP810 is not set
# end of Pressure sensors

#
# Lightning sensors
#
# CONFIG_AS3935 is not set
# end of Lightning sensors

#
# Proximity and distance sensors
#
# CONFIG_D3323AA is not set
# CONFIG_HX9023S is not set
# CONFIG_IRSD200 is not set
# CONFIG_ISL29501 is not set
# CONFIG_LIDAR_LITE_V2 is not set
# CONFIG_MB1232 is not set
# CONFIG_PING is not set
# CONFIG_RFD77402 is not set
# CONFIG_SRF04 is not set
# CONFIG_SX9310 is not set
# CONFIG_SX9324 is not set
# CONFIG_SX9360 is not set
# CONFIG_SX9500 is not set
# CONFIG_SRF08 is not set
# CONFIG_VCNL3020 is not set
# CONFIG_VL53L0X_I2C is not set
# CONFIG_VL53L1X_I2C is not set
# CONFIG_AW96103 is not set
# end of Proximity and distance sensors

#
# Resolver to digital converters
#
# CONFIG_AD2S90 is not set
# CONFIG_AD2S1200 is not set
# CONFIG_AD2S1210 is not set
# end of Resolver to digital converters

#
# Temperature sensors
#
# CONFIG_LTC2983 is not set
# CONFIG_MAXIM_THERMOCOUPLE is not set
CONFIG_HID_SENSOR_TEMP=y
# CONFIG_MLX90614 is not set
# CONFIG_MLX90632 is not set
# CONFIG_MLX90635 is not set
# CONFIG_TMP006 is not set
# CONFIG_TMP007 is not set
# CONFIG_TMP117 is not set
# CONFIG_TSYS01 is not set
# CONFIG_TSYS02D is not set
# CONFIG_MAX30208 is not set
# CONFIG_MAX31856 is not set
# CONFIG_MAX31865 is not set
# CONFIG_MCP9600 is not set
# end of Temperature sensors

# CONFIG_NTB is not set
# CONFIG_PWM is not set

#
# IRQ chip support
#
CONFIG_IRQCHIP=y
CONFIG_IRQ_MSI_LIB=y
# CONFIG_AL_FIC is not set
# CONFIG_XILINX_INTC is not set
# end of IRQ chip support

# CONFIG_IPACK_BUS is not set
CONFIG_RESET_CONTROLLER=y
# CONFIG_RESET_GPIO is not set
# CONFIG_RESET_INTEL_GW is not set
# CONFIG_RESET_SIMPLE is not set
# CONFIG_RESET_TI_SYSCON is not set
# CONFIG_RESET_TI_TPS380X is not set

#
# PHY Subsystem
#
CONFIG_GENERIC_PHY=y
# CONFIG_PHY_CAN_TRANSCEIVER is not set
CONFIG_PHY_GOOGLE_USB=y
CONFIG_USB_LGM_PHY=y
# CONFIG_PHY_NXP_PTN3222 is not set
# CONFIG_PHY_NXP_TJA1145 is not set

#
# PHY drivers for Broadcom platforms
#
# CONFIG_BCM_KONA_USB2_PHY is not set
# end of PHY drivers for Broadcom platforms

# CONFIG_PHY_CADENCE_TORRENT is not set
# CONFIG_PHY_CADENCE_DPHY is not set
# CONFIG_PHY_CADENCE_DPHY_RX is not set
# CONFIG_PHY_CADENCE_SIERRA is not set
# CONFIG_PHY_CADENCE_SALVO is not set
# CONFIG_PHY_INTEL_LGM_COMBO is not set
# CONFIG_PHY_INTEL_LGM_EMMC is not set
# CONFIG_PHY_PXA_28NM_HSIC is not set
# CONFIG_PHY_PXA_28NM_USB2 is not set
CONFIG_PHY_CPCAP_USB=y
# CONFIG_PHY_MAPPHONE_MDM6600 is not set
# CONFIG_PHY_OCELOT_SERDES is not set
CONFIG_PHY_QCOM_USB_HS=y
CONFIG_PHY_QCOM_USB_HSIC=y
CONFIG_PHY_SAMSUNG_USB2=y
# CONFIG_PHY_TI_DS125DF111 is not set
CONFIG_PHY_TUSB1210=y
# end of PHY Subsystem

# CONFIG_POWERCAP is not set
# CONFIG_MCB is not set

#
# Performance monitor support
#
# CONFIG_DWC_PCIE_PMU is not set
# end of Performance monitor support

CONFIG_RAS=y
CONFIG_USB4=y
CONFIG_USB4_CONFIGFS=y
# CONFIG_USB4_DEBUGFS_WRITE is not set
# CONFIG_USB4_DMA_TEST is not set
# CONFIG_USB4_STREAM is not set

#
# Android
#
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDERFS=y
CONFIG_ANDROID_BINDER_DEVICES="binder0,binder1"
# end of Android

CONFIG_LIBNVDIMM=y
CONFIG_BLK_DEV_PMEM=y
CONFIG_ND_CLAIM=y
CONFIG_ND_BTT=y
CONFIG_BTT=y
CONFIG_ND_PFN=y
CONFIG_NVDIMM_PFN=y
CONFIG_NVDIMM_DAX=y
CONFIG_OF_PMEM=y
# CONFIG_RAMDAX is not set
CONFIG_NVDIMM_KEYS=y
# CONFIG_NVDIMM_SECURITY_TEST is not set
CONFIG_DAX=y
CONFIG_DEV_DAX=y
# CONFIG_DEV_DAX_PMEM is not set
CONFIG_DEV_DAX_FSDEV=y
# CONFIG_DEV_DAX_KMEM is not set
CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
CONFIG_NVMEM_LAYOUTS=y

#
# Layout Types
#
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
# end of Layout Types

# CONFIG_NVMEM_RMEM is not set
# CONFIG_NVMEM_U_BOOT_ENV is not set

#
# HW tracing support
#
# CONFIG_STM is not set
# CONFIG_INTEL_TH is not set
# end of HW tracing support

# CONFIG_FPGA is not set
# CONFIG_FSI is not set
CONFIG_TEE=y
CONFIG_TEE_DMABUF_HEAPS=y
CONFIG_OPTEE_STATIC_PROTMEM_POOL=y
# CONFIG_MUX_CORE is not set
# CONFIG_SIOX is not set
# CONFIG_SLIMBUS is not set
# CONFIG_INTERCONNECT is not set
CONFIG_COUNTER=y
# CONFIG_INTEL_QEP is not set
# CONFIG_INTERRUPT_CNT is not set
CONFIG_MOST=y
CONFIG_MOST_USB_HDM=y
# CONFIG_MOST_CDEV is not set
# CONFIG_MOST_SND is not set
# CONFIG_PECI is not set
# CONFIG_HTE is not set
# end of Device Drivers

#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_VALIDATE_FS_PARSER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_STACK=y
CONFIG_BUFFER_HEAD=y
CONFIG_LEGACY_DIRECT_IO=y
# CONFIG_EXT2_FS is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_USE_FOR_EXT2=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD2=y
# CONFIG_JBD2_DEBUG is not set
CONFIG_FS_MBCACHE=y
CONFIG_JFS_FS=y
CONFIG_JFS_POSIX_ACL=y
CONFIG_JFS_SECURITY=y
CONFIG_JFS_DEBUG=y
# CONFIG_JFS_STATISTICS is not set
CONFIG_XFS_FS=y
# CONFIG_XFS_SUPPORT_V4 is not set
# CONFIG_XFS_SUPPORT_ASCII_CI is not set
CONFIG_XFS_QUOTA=y
CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XFS_DRAIN_INTENTS=y
CONFIG_XFS_LIVE_HOOKS=y
CONFIG_XFS_MEMORY_BUFS=y
CONFIG_XFS_BTREE_IN_MEM=y
CONFIG_XFS_ONLINE_SCRUB=y
# CONFIG_XFS_ONLINE_SCRUB_STATS is not set
CONFIG_XFS_ONLINE_REPAIR=y
# CONFIG_XFS_WARN is not set
# CONFIG_XFS_DEBUG is not set
CONFIG_GFS2_FS=y
CONFIG_GFS2_FS_LOCKING_DLM=y
CONFIG_OCFS2_FS=y
CONFIG_OCFS2_FS_O2CB=y
CONFIG_OCFS2_FS_USERSPACE_CLUSTER=y
CONFIG_OCFS2_FS_STATS=y
# CONFIG_OCFS2_DEBUG_MASKLOG is not set
CONFIG_OCFS2_DEBUG_FS=y
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS_POSIX_ACL=y
# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
# CONFIG_BTRFS_DEBUG is not set
CONFIG_BTRFS_ASSERT=y
# CONFIG_BTRFS_EXPERIMENTAL is not set
CONFIG_NILFS2_FS=y
CONFIG_F2FS_FS=y
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
CONFIG_F2FS_FS_POSIX_ACL=y
CONFIG_F2FS_FS_SECURITY=y
CONFIG_F2FS_CHECK_FS=y
CONFIG_F2FS_FAULT_INJECTION=y
CONFIG_F2FS_FS_COMPRESSION=y
CONFIG_F2FS_FS_LZO=y
CONFIG_F2FS_FS_LZORLE=y
CONFIG_F2FS_FS_LZ4=y
CONFIG_F2FS_FS_LZ4HC=y
CONFIG_F2FS_FS_ZSTD=y
# CONFIG_F2FS_IOSTAT is not set
# CONFIG_F2FS_UNFAIR_RWSEM is not set
CONFIG_ZONEFS_FS=y
CONFIG_FS_DAX=y
CONFIG_FS_DAX_PMD=y
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
CONFIG_EXPORTFS_BLOCK_OPS=y
CONFIG_FILE_LOCKING=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
# CONFIG_FS_ENCRYPTION_INLINE_CRYPT is not set
CONFIG_FS_VERITY=y
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_QUOTA_DEBUG is not set
CONFIG_QUOTA_TREE=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
CONFIG_AUTOFS_FS=y
CONFIG_FUSE_FS=y
CONFIG_CUSE=y
CONFIG_VIRTIO_FS=y
CONFIG_FUSE_DAX=y
# CONFIG_FUSE_PASSTHROUGH is not set
# CONFIG_FUSE_IO_URING is not set
CONFIG_OVERLAY_FS=y
CONFIG_OVERLAY_FS_REDIRECT_DIR=y
CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
CONFIG_OVERLAY_FS_INDEX=y
# CONFIG_OVERLAY_FS_NFS_EXPORT is not set
# CONFIG_OVERLAY_FS_XINO_AUTO is not set
# CONFIG_OVERLAY_FS_METACOPY is not set
CONFIG_OVERLAY_FS_DEBUG=y

#
# Caches
#
CONFIG_NETFS_SUPPORT=y
# CONFIG_NETFS_STATS is not set
# CONFIG_NETFS_DEBUG is not set
CONFIG_FSCACHE=y
# CONFIG_FSCACHE_STATS is not set
CONFIG_CACHEFILES=y
# CONFIG_CACHEFILES_DEBUG is not set
# CONFIG_CACHEFILES_ERROR_INJECTION is not set
# CONFIG_CACHEFILES_ONDEMAND is not set
# end of Caches

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
CONFIG_ZISOFS=y
CONFIG_UDF_FS=y
# end of CD-ROM/DVD Filesystems

#
# DOS/FAT/EXFAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_FAT_DEFAULT_UTF8 is not set
CONFIG_EXFAT_FS=y
CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
# CONFIG_NTFS_FS is not set
CONFIG_NTFS3_FS=y
# CONFIG_NTFS3_64BIT_CLUSTER is not set
CONFIG_NTFS3_LZX_XPRESS=y
CONFIG_NTFS3_FS_POSIX_ACL=y
# end of DOS/FAT/EXFAT/NT Filesystems

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_VMCORE=y
# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_PROC_CHILDREN=y
CONFIG_PROC_PID_ARCH_STATUS=y
CONFIG_KERNFS=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TMPFS_XATTR=y
# CONFIG_TMPFS_INODE64 is not set
CONFIG_TMPFS_QUOTA=y
CONFIG_ARCH_SUPPORTS_HUGETLBFS=y
CONFIG_HUGETLBFS=y
# CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON is not set
CONFIG_HUGETLB_PAGE=y
CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING=y
CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
CONFIG_CONFIGFS_FS=y
# end of Pseudo filesystems

CONFIG_MISC_FILESYSTEMS=y
CONFIG_ORANGEFS_FS=y
CONFIG_ADFS_FS=y
# CONFIG_ADFS_FS_RW is not set
CONFIG_AFFS_FS=y
CONFIG_ECRYPT_FS=y
CONFIG_ECRYPT_FS_MESSAGING=y
CONFIG_HFS_FS=y
CONFIG_HFSPLUS_FS=y
CONFIG_BEFS_FS=y
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=y
CONFIG_EFS_FS=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
CONFIG_JFFS2_FS_POSIX_ACL=y
CONFIG_JFFS2_FS_SECURITY=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_LZO=y
CONFIG_JFFS2_RTIME=y
CONFIG_JFFS2_RUBIN=y
# CONFIG_JFFS2_CMODE_NONE is not set
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
CONFIG_UBIFS_FS=y
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UBIFS_FS_ZSTD=y
CONFIG_UBIFS_ATIME_SUPPORT=y
CONFIG_UBIFS_FS_XATTR=y
CONFIG_UBIFS_FS_SECURITY=y
# CONFIG_UBIFS_FS_AUTHENTICATION is not set
CONFIG_CRAMFS=y
CONFIG_CRAMFS_BLOCKDEV=y
CONFIG_CRAMFS_MTD=y
CONFIG_SQUASHFS=y
# CONFIG_SQUASHFS_FILE_CACHE is not set
CONFIG_SQUASHFS_FILE_DIRECT=y
CONFIG_SQUASHFS_DECOMP_MULTI=y
# CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set
# CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE is not set
CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI=y
# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set
# CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS is not set
CONFIG_SQUASHFS_XATTR=y
# CONFIG_SQUASHFS_COMP_CACHE_FULL is not set
CONFIG_SQUASHFS_ZLIB=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_SQUASHFS_LZO=y
CONFIG_SQUASHFS_XZ=y
CONFIG_SQUASHFS_ZSTD=y
CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
# CONFIG_SQUASHFS_EMBEDDED is not set
CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
CONFIG_VXFS_FS=y
CONFIG_MINIX_FS=y
CONFIG_OMFS_FS=y
CONFIG_HPFS_FS=y
CONFIG_QNX4FS_FS=y
CONFIG_QNX6FS_FS=y
# CONFIG_QNX6FS_DEBUG is not set
CONFIG_ROMFS_FS=y
# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
# CONFIG_ROMFS_BACKED_BY_MTD is not set
CONFIG_ROMFS_BACKED_BY_BOTH=y
CONFIG_ROMFS_ON_BLOCK=y
CONFIG_ROMFS_ON_MTD=y
CONFIG_PSTORE=y
CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
CONFIG_PSTORE_COMPRESS=y
# CONFIG_PSTORE_CONSOLE is not set
# CONFIG_PSTORE_PMSG is not set
# CONFIG_PSTORE_RAM is not set
# CONFIG_PSTORE_BLK is not set
CONFIG_UFS_FS=y
CONFIG_UFS_FS_WRITE=y
# CONFIG_UFS_DEBUG is not set
CONFIG_EROFS_FS=y
# CONFIG_EROFS_FS_DEBUG is not set
CONFIG_EROFS_FS_XATTR=y
CONFIG_EROFS_FS_POSIX_ACL=y
CONFIG_EROFS_FS_SECURITY=y
# CONFIG_EROFS_FS_BACKED_BY_FILE is not set
CONFIG_EROFS_FS_ZIP=y
# CONFIG_EROFS_FS_ZIP_LZMA is not set
# CONFIG_EROFS_FS_ZIP_DEFLATE is not set
# CONFIG_EROFS_FS_ZIP_ZSTD is not set
# CONFIG_EROFS_FS_ZIP_ACCEL is not set
# CONFIG_EROFS_FS_PCPU_KTHREAD is not set
# CONFIG_EROFS_FS_PAGE_CACHE_SHARE is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V2 is not set
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
# CONFIG_NFS_SWAP is not set
CONFIG_NFS_V4_0=y
CONFIG_NFS_V4_2=y
CONFIG_PNFS_FILE_LAYOUT=y
CONFIG_PNFS_BLOCK=y
CONFIG_PNFS_FLEXFILE_LAYOUT=y
CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org"
# CONFIG_NFS_V4_1_MIGRATION is not set
CONFIG_NFS_V4_SECURITY_LABEL=y
CONFIG_ROOT_NFS=y
CONFIG_NFS_FSCACHE=y
# CONFIG_NFS_USE_LEGACY_DNS is not set
CONFIG_NFS_USE_KERNEL_DNS=y
# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set
CONFIG_NFS_V4_2_READ_PLUS=y
CONFIG_NFSD=y
# CONFIG_NFSD_V2 is not set
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_PNFS=y
CONFIG_NFSD_BLOCKLAYOUT=y
CONFIG_NFSD_SCSILAYOUT=y
CONFIG_NFSD_FLEXFILELAYOUT=y
CONFIG_NFSD_V4_2_INTER_SSC=y
CONFIG_NFSD_V4_SECURITY_LABEL=y
# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set
# CONFIG_NFSD_V4_POSIX_ACLS is not set
CONFIG_GRACE_PERIOD=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y
# CONFIG_NFS_LOCALIO is not set
CONFIG_NFS_V4_2_SSC_HELPER=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_SUNRPC_BACKCHANNEL=y
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_SUNRPC_DEBUG is not set
# CONFIG_SUNRPC_XPRT_RDMA is not set
CONFIG_CEPH_FS=y
CONFIG_CEPH_FSCACHE=y
CONFIG_CEPH_FS_POSIX_ACL=y
# CONFIG_CEPH_FS_SECURITY_LABEL is not set
CONFIG_CIFS=y
# CONFIG_CIFS_STATS2 is not set
CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_CIFS_DEBUG=y
# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set
CONFIG_CIFS_DFS_UPCALL=y
CONFIG_CIFS_SWN_UPCALL=y
CONFIG_CIFS_SMB_DIRECT=y
CONFIG_CIFS_FSCACHE=y
# CONFIG_CIFS_ROOT is not set
# CONFIG_CIFS_COMPRESSION is not set
CONFIG_SMB_SERVER=y
# CONFIG_SMB_SERVER_SMBDIRECT is not set
# CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN is not set
# CONFIG_SMB_SERVER_KERBEROS5 is not set
CONFIG_SMBDIRECT=y
CONFIG_SMBFS=y
# CONFIG_CODA_FS is not set
CONFIG_AFS_FS=y
# CONFIG_AFS_DEBUG is not set
CONFIG_AFS_FSCACHE=y
# CONFIG_AFS_DEBUG_CURSOR is not set
CONFIG_9P_FS=y
CONFIG_9P_FSCACHE=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=y
CONFIG_NLS_CODEPAGE_775=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_CODEPAGE_852=y
CONFIG_NLS_CODEPAGE_855=y
CONFIG_NLS_CODEPAGE_857=y
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=y
CONFIG_NLS_CODEPAGE_862=y
CONFIG_NLS_CODEPAGE_863=y
CONFIG_NLS_CODEPAGE_864=y
CONFIG_NLS_CODEPAGE_865=y
CONFIG_NLS_CODEPAGE_866=y
CONFIG_NLS_CODEPAGE_869=y
CONFIG_NLS_CODEPAGE_936=y
CONFIG_NLS_CODEPAGE_950=y
CONFIG_NLS_CODEPAGE_932=y
CONFIG_NLS_CODEPAGE_949=y
CONFIG_NLS_CODEPAGE_874=y
CONFIG_NLS_ISO8859_8=y
CONFIG_NLS_CODEPAGE_1250=y
CONFIG_NLS_CODEPAGE_1251=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_ISO8859_3=y
CONFIG_NLS_ISO8859_4=y
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
CONFIG_NLS_ISO8859_9=y
CONFIG_NLS_ISO8859_13=y
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_KOI8_U=y
CONFIG_NLS_MAC_ROMAN=y
CONFIG_NLS_MAC_CELTIC=y
CONFIG_NLS_MAC_CENTEURO=y
CONFIG_NLS_MAC_CROATIAN=y
CONFIG_NLS_MAC_CYRILLIC=y
CONFIG_NLS_MAC_GAELIC=y
CONFIG_NLS_MAC_GREEK=y
CONFIG_NLS_MAC_ICELAND=y
CONFIG_NLS_MAC_INUIT=y
CONFIG_NLS_MAC_ROMANIAN=y
CONFIG_NLS_MAC_TURKISH=y
CONFIG_NLS_UTF8=y
CONFIG_NLS_UCS2_UTILS=y
CONFIG_DLM=y
# CONFIG_DLM_DEBUG is not set
CONFIG_UNICODE=y
CONFIG_IO_WQ=y
# end of File systems

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_REQUEST_CACHE=y
CONFIG_PERSISTENT_KEYRINGS=y
CONFIG_BIG_KEYS=y
CONFIG_TRUSTED_KEYS=y
# CONFIG_TRUSTED_KEYS_TPM is not set
# CONFIG_TRUSTED_KEYS_TEE is not set

#
# No trust source selected!
#
CONFIG_ENCRYPTED_KEYS=y
# CONFIG_USER_DECRYPTED_DATA is not set
CONFIG_KEY_DH_OPERATIONS=y
CONFIG_KEY_NOTIFICATIONS=y
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_PROC_MEM_ALWAYS_FORCE is not set
CONFIG_PROC_MEM_FORCE_PTRACE=y
# CONFIG_PROC_MEM_NO_FORCE is not set
CONFIG_SECURITY=y
CONFIG_HAS_SECURITY_AUDIT=y
CONFIG_SECURITYFS=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_INFINIBAND=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_PATH=y
# CONFIG_INTEL_TXT is not set
# CONFIG_STATIC_USERMODEHELPER is not set
# CONFIG_SECURITY_SELINUX is not set
# CONFIG_SECURITY_SMACK is not set
CONFIG_SECURITY_TOMOYO=y
CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=64
CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=32
CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER=y
CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING=y
CONFIG_SECURITY_APPARMOR=y
CONFIG_SECURITY_APPARMOR_DEBUG=y
CONFIG_SECURITY_APPARMOR_DEBUG_ASSERTS=y
# CONFIG_SECURITY_APPARMOR_DEBUG_MESSAGES is not set
CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY=y
CONFIG_SECURITY_APPARMOR_HASH=y
CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y
# CONFIG_SECURITY_APPARMOR_EXPORT_BINARY is not set
# CONFIG_SECURITY_APPARMOR_PARANOID_LOAD is not set
# CONFIG_SECURITY_LOADPIN is not set
CONFIG_SECURITY_YAMA=y
CONFIG_SECURITY_SAFESETID=y
CONFIG_SECURITY_LOCKDOWN_LSM=y
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y
# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set
# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set
CONFIG_SECURITY_LANDLOCK=y
# CONFIG_SECURITY_IPE is not set
CONFIG_INTEGRITY=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
CONFIG_INTEGRITY_TRUSTED_KEYRING=y
CONFIG_INTEGRITY_AUDIT=y
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
CONFIG_IMA_LSM_RULES=y
CONFIG_IMA_NG_TEMPLATE=y
# CONFIG_IMA_SIG_TEMPLATE is not set
CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng"
# CONFIG_IMA_DEFAULT_HASH_SHA1 is not set
CONFIG_IMA_DEFAULT_HASH_SHA256=y
# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set
# CONFIG_IMA_DEFAULT_HASH_WP512 is not set
CONFIG_IMA_DEFAULT_HASH="sha256"
CONFIG_IMA_WRITE_POLICY=y
CONFIG_IMA_READ_POLICY=y
CONFIG_IMA_APPRAISE=y
# CONFIG_IMA_ARCH_POLICY is not set
# CONFIG_IMA_APPRAISE_BUILD_POLICY is not set
# CONFIG_IMA_APPRAISE_BOOTPARAM is not set
CONFIG_IMA_APPRAISE_MODSIG=y
# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set
# CONFIG_IMA_BLACKLIST_KEYRING is not set
# CONFIG_IMA_LOAD_X509 is not set
CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y
CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y
# CONFIG_IMA_DISABLE_HTABLE is not set
# CONFIG_IMA_STAGING is not set
CONFIG_EVM=y
CONFIG_EVM_ATTR_FSUUID=y
CONFIG_EVM_ADD_XATTRS=y
# CONFIG_EVM_LOAD_X509 is not set
# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
CONFIG_DEFAULT_SECURITY_APPARMOR=y
# CONFIG_DEFAULT_SECURITY_DAC is not set
CONFIG_LSM="landlock,lockdown,yama,safesetid,integrity,tomoyo,apparmor,bpf"

#
# Kernel hardening options
#

#
# Memory initialization
#
CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y
CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y
# CONFIG_INIT_STACK_NONE is not set
# CONFIG_INIT_STACK_ALL_PATTERN is not set
CONFIG_INIT_STACK_ALL_ZERO=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
# CONFIG_ZERO_CALL_USED_REGS is not set
# end of Memory initialization

#
# Bounds checking
#
CONFIG_FORTIFY_SOURCE=y
CONFIG_HARDENED_USERCOPY=y
# CONFIG_HARDENED_USERCOPY_DEFAULT_ON is not set
# end of Bounds checking

#
# Hardening of kernel data structures
#
CONFIG_LIST_HARDENED=y
CONFIG_BUG_ON_DATA_CORRUPTION=y
# end of Hardening of kernel data structures

CONFIG_RANDSTRUCT_NONE=y
# end of Kernel hardening options
# end of Security options

CONFIG_ASYNC_CORE=y
CONFIG_ASYNC_MEMCPY=y
CONFIG_ASYNC_XOR=y
CONFIG_ASYNC_PQ=y
CONFIG_ASYNC_RAID6_RECOV=y
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_SIG=y
CONFIG_CRYPTO_SIG2=y
CONFIG_CRYPTO_SKCIPHER=y
CONFIG_CRYPTO_SKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_AKCIPHER2=y
CONFIG_CRYPTO_AKCIPHER=y
CONFIG_CRYPTO_KPP2=y
CONFIG_CRYPTO_KPP=y
CONFIG_CRYPTO_ACOMP2=y
CONFIG_CRYPTO_ACOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_USER=y
# CONFIG_CRYPTO_SELFTESTS is not set
# CONFIG_CRYPTO_NULL is not set
CONFIG_CRYPTO_PCRYPT=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_KRB5ENC=y
# CONFIG_CRYPTO_BENCHMARK is not set
CONFIG_CRYPTO_ENGINE=y
# end of Crypto core or helper

#
# Public-key cryptography
#
CONFIG_CRYPTO_RSA=y
CONFIG_CRYPTO_DH=y
# CONFIG_CRYPTO_DH_RFC7919_GROUPS is not set
CONFIG_CRYPTO_ECC=y
CONFIG_CRYPTO_ECDH=y
# CONFIG_CRYPTO_ECDSA is not set
CONFIG_CRYPTO_ECRDSA=y
CONFIG_CRYPTO_MLDSA=y
# end of Public-key cryptography

#
# Block ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ANUBIS=y
CONFIG_CRYPTO_ARIA=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_BLOWFISH_COMMON=y
CONFIG_CRYPTO_CAMELLIA=y
CONFIG_CRYPTO_CAST_COMMON=y
CONFIG_CRYPTO_CAST5=y
CONFIG_CRYPTO_CAST6=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_KHAZAD=y
CONFIG_CRYPTO_SEED=y
CONFIG_CRYPTO_SERPENT=y
CONFIG_CRYPTO_SM4=y
CONFIG_CRYPTO_SM4_GENERIC=y
CONFIG_CRYPTO_TEA=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y
# end of Block ciphers

#
# Length-preserving ciphers and modes
#
CONFIG_CRYPTO_ADIANTUM=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_CHACHA20=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_HCTR2=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_XCTR=y
CONFIG_CRYPTO_XTS=y
# end of Length-preserving ciphers and modes

#
# AEAD (authenticated encryption with associated data) ciphers
#
CONFIG_CRYPTO_AEGIS128=y
CONFIG_CRYPTO_CHACHA20POLY1305=y
CONFIG_CRYPTO_CCM=y
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_GENIV=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_ESSIV=y
# end of AEAD (authenticated encryption with associated data) ciphers

#
# Hashes, digests, and MACs
#
# CONFIG_CRYPTO_BLAKE2B is not set
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
CONFIG_CRYPTO_RMD160=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_SHA3=y
# CONFIG_CRYPTO_SM3 is not set
CONFIG_CRYPTO_STREEBOG=y
CONFIG_CRYPTO_WP512=y
CONFIG_CRYPTO_XCBC=y
# CONFIG_CRYPTO_XXHASH is not set
# end of Hashes, digests, and MACs

#
# CRCs (cyclic redundancy checks)
#
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CRC32 is not set
# end of CRCs (cyclic redundancy checks)

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_842=y
CONFIG_CRYPTO_LZ4=y
CONFIG_CRYPTO_LZ4HC=y
CONFIG_CRYPTO_ZSTD=y
# end of Compression

#
# Random number generation
#
# CONFIG_CRYPTO_DRBG is not set
# CONFIG_CRYPTO_JITTERENTROPY is not set
CONFIG_CRYPTO_KDF800108_CTR=y
# end of Random number generation

#
# Userspace interface (deprecated)
#
CONFIG_CRYPTO_USER_API=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CRYPTO_USER_API_SKCIPHER=y
CONFIG_CRYPTO_USER_API_RNG=y
CONFIG_CRYPTO_USER_API_AEAD=y
CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y
# end of Userspace interface (deprecated)

#
# Accelerated Cryptographic Algorithms for CPU (x86)
#
CONFIG_CRYPTO_AES_NI_INTEL=y
CONFIG_CRYPTO_BLOWFISH_X86_64=y
CONFIG_CRYPTO_CAMELLIA_X86_64=y
CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=y
CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=y
CONFIG_CRYPTO_CAST5_AVX_X86_64=y
CONFIG_CRYPTO_CAST6_AVX_X86_64=y
CONFIG_CRYPTO_SERPENT_SSE2_X86_64=y
CONFIG_CRYPTO_SERPENT_AVX_X86_64=y
CONFIG_CRYPTO_SERPENT_AVX2_X86_64=y
CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64=y
CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64=y
CONFIG_CRYPTO_TWOFISH_X86_64=y
CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=y
CONFIG_CRYPTO_TWOFISH_AVX_X86_64=y
CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64=y
# CONFIG_CRYPTO_ARIA_AESNI_AVX2_X86_64 is not set
# CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64 is not set
CONFIG_CRYPTO_AEGIS128_AESNI_SSE2=y
# end of Accelerated Cryptographic Algorithms for CPU (x86)

CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_PADLOCK=y
CONFIG_CRYPTO_DEV_PADLOCK_AES=y
CONFIG_CRYPTO_DEV_PADLOCK_SHA=y
# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
CONFIG_CRYPTO_DEV_CCP=y
CONFIG_CRYPTO_DEV_CCP_DD=y
# CONFIG_CRYPTO_DEV_SP_CCP is not set
# CONFIG_CRYPTO_DEV_SP_PSP is not set
# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set
CONFIG_CRYPTO_DEV_QAT=y
CONFIG_CRYPTO_DEV_QAT_DH895xCC=y
CONFIG_CRYPTO_DEV_QAT_C3XXX=y
CONFIG_CRYPTO_DEV_QAT_C62X=y
# CONFIG_CRYPTO_DEV_QAT_4XXX is not set
# CONFIG_CRYPTO_DEV_QAT_420XX is not set
# CONFIG_CRYPTO_DEV_QAT_6XXX is not set
CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=y
CONFIG_CRYPTO_DEV_QAT_C3XXXVF=y
CONFIG_CRYPTO_DEV_QAT_C62XVF=y
# CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION is not set
CONFIG_CRYPTO_DEV_VIRTIO=y
# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
# CONFIG_CRYPTO_DEV_CCREE is not set
# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_PKCS8_PRIVATE_KEY_PARSER=y
CONFIG_PKCS7_MESSAGE_PARSER=y
# CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA is not set
CONFIG_PKCS7_TEST_KEY=y
CONFIG_SIGNED_PE_FILE_VERIFICATION=y
# CONFIG_FIPS_SIGNATURE_SELFTEST is not set

#
# Certificates for signature checking
#
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
# CONFIG_MODULE_SIG_KEY_TYPE_RSA is not set
CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_44=y
# CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_65 is not set
# CONFIG_MODULE_SIG_KEY_TYPE_MLDSA_87 is not set
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS=""
# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set
CONFIG_SECONDARY_TRUSTED_KEYRING=y
# CONFIG_SECONDARY_TRUSTED_KEYRING_SIGNED_BY_BUILTIN is not set
# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
CONFIG_OPENSSL_SUPPORTS_ML_DSA=y
# end of Certificates for signature checking

CONFIG_CRYPTO_KRB5=y
# CONFIG_CRYPTO_KRB5_SELFTESTS is not set
CONFIG_BINARY_PRINTF=y

#
# Library routines
#
CONFIG_LINEAR_RANGES=y
# CONFIG_PACKING is not set
CONFIG_BITREVERSE=y
CONFIG_GENERIC_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
# CONFIG_CORDIC is not set
# CONFIG_PRIME_NUMBERS is not set
CONFIG_RATIONAL=y
CONFIG_GENERIC_IOMAP=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
CONFIG_ARCH_USE_SYM_ANNOTATIONS=y
CONFIG_CRC8=y
CONFIG_CRC16=y
CONFIG_CRC_CCITT=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_T10DIF_ARCH=y
CONFIG_CRC32=y
CONFIG_CRC32_ARCH=y
CONFIG_CRC64=y
CONFIG_CRC64_ARCH=y
CONFIG_CRC_OPTIMIZATIONS=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LIB_AES=y
CONFIG_CRYPTO_LIB_AES_ARCH=y
CONFIG_CRYPTO_LIB_AES_CBC_MACS=y
CONFIG_CRYPTO_LIB_ARC4=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_BLAKE2B=y
CONFIG_CRYPTO_LIB_BLAKE2S_ARCH=y
CONFIG_CRYPTO_LIB_CHACHA=y
CONFIG_CRYPTO_LIB_CHACHA_ARCH=y
CONFIG_CRYPTO_LIB_CURVE25519=y
CONFIG_CRYPTO_LIB_CURVE25519_ARCH=y
CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y
CONFIG_CRYPTO_LIB_DES=y
CONFIG_CRYPTO_LIB_GF128HASH=y
CONFIG_CRYPTO_LIB_GF128HASH_ARCH=y
CONFIG_CRYPTO_LIB_MD5=y
CONFIG_CRYPTO_LIB_MLDSA=y
CONFIG_CRYPTO_LIB_NH=y
CONFIG_CRYPTO_LIB_NH_ARCH=y
CONFIG_CRYPTO_LIB_POLY1305=y
CONFIG_CRYPTO_LIB_POLY1305_ARCH=y
CONFIG_CRYPTO_LIB_POLY1305_GENERIC=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11
CONFIG_CRYPTO_LIB_CHACHA20POLY1305=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA1_ARCH=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_SHA256_ARCH=y
CONFIG_CRYPTO_LIB_SHA512=y
CONFIG_CRYPTO_LIB_SHA512_ARCH=y
CONFIG_CRYPTO_LIB_SHA3=y
CONFIG_XOR_BLOCKS=y
CONFIG_XOR_BLOCKS_ARCH=y
CONFIG_RAID6_PQ=y
CONFIG_RAID6_PQ_ARCH=y
# CONFIG_RAID6_PQ_BENCHMARK is not set
CONFIG_XXHASH=y
# CONFIG_RANDOM32_SELFTEST is not set
CONFIG_842_COMPRESS=y
CONFIG_842_DECOMPRESS=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_LZ4_COMPRESS=y
CONFIG_LZ4HC_COMPRESS=y
CONFIG_LZ4_DECOMPRESS=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_X86=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_ARM64=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_RISCV=y
# CONFIG_XZ_DEC_MICROLZMA is not set
CONFIG_XZ_DEC_BCJ=y
# CONFIG_XZ_DEC_TEST is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_DECOMPRESS_ZSTD=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_REED_SOLOMON=y
CONFIG_REED_SOLOMON_DEC8=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=y
CONFIG_TEXTSEARCH_BM=y
CONFIG_TEXTSEARCH_FSM=y
CONFIG_INTERVAL_TREE=y
CONFIG_INTERVAL_TREE_SPAN_ITER=y
CONFIG_XARRAY_MULTI=y
CONFIG_ASSOCIATIVE_ARRAY=y
CONFIG_CLOSURES=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAS_DMA=y
CONFIG_DMA_OPS_HELPERS=y
CONFIG_NEED_SG_DMA_FLAGS=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_DMA_DECLARE_COHERENT=y
CONFIG_SWIOTLB=y
# CONFIG_SWIOTLB_DYNAMIC is not set
CONFIG_DMA_NEED_SYNC=y
# CONFIG_DMA_RESTRICTED_POOL is not set
CONFIG_DMA_CMA=y
# CONFIG_DMA_NUMA_CMA is not set

#
# Default contiguous memory area size:
#
CONFIG_CMA_SIZE_MBYTES=0
CONFIG_CMA_SIZE_PERCENTAGE=0
# CONFIG_CMA_SIZE_SEL_MBYTES is not set
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
# CONFIG_CMA_SIZE_SEL_MIN is not set
CONFIG_CMA_SIZE_SEL_MAX=y
CONFIG_CMA_ALIGNMENT=8
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_DMA_MAP_BENCHMARK is not set
CONFIG_SGL_ALLOC=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_CPU_RMAP=y
CONFIG_DQL=y
CONFIG_GLOB=y
CONFIG_NLATTR=y
CONFIG_CLZ_TAB=y
CONFIG_IRQ_POLL=y
CONFIG_MPILIB=y
CONFIG_SIGNATURE=y
CONFIG_DIMLIB=y
CONFIG_LIBFDT=y
CONFIG_OID_REGISTRY=y
CONFIG_HAVE_GENERIC_VDSO=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT=y
CONFIG_VDSO_GETRANDOM=y
CONFIG_FONT_SUPPORT=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_SG_POOL=y
CONFIG_ARCH_HAS_PMEM_API=y
CONFIG_MEMREGION=y
CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION=y
CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y
CONFIG_ARCH_HAS_COPY_MC=y
CONFIG_ARCH_STACKWALK=y
CONFIG_STACKDEPOT=y
CONFIG_STACKDEPOT_ALWAYS_INIT=y
CONFIG_STACKDEPOT_MAX_FRAMES=64
CONFIG_REF_TRACKER=y
CONFIG_SBITMAP=y
# CONFIG_LWQ_TEST is not set
# end of Library routines

CONFIG_FIRMWARE_TABLE=y
CONFIG_UNION_FIND=y

#
# Kernel hacking
#

#
# printk and dmesg options
#
CONFIG_PRINTK_TIME=y
CONFIG_PRINTK_CALLER=y
# CONFIG_STACKTRACE_BUILD_ID is not set
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
CONFIG_CONSOLE_LOGLEVEL_QUIET=4
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DYNAMIC_DEBUG_CORE is not set
CONFIG_SYMBOLIC_ERRNAME=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_BUGVERBOSE_DETAILED is not set
# end of printk and dmesg options

CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MISC=y

#
# Compile-time checks and compiler options
#
CONFIG_DEBUG_INFO=y
CONFIG_AS_HAS_NON_CONST_ULEB128=y
# CONFIG_DEBUG_INFO_NONE is not set
# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
CONFIG_DEBUG_INFO_DWARF4=y
# CONFIG_DEBUG_INFO_DWARF5 is not set
# CONFIG_DEBUG_INFO_REDUCED is not set
CONFIG_DEBUG_INFO_COMPRESSED_NONE=y
# CONFIG_DEBUG_INFO_COMPRESSED_ZLIB is not set
# CONFIG_DEBUG_INFO_COMPRESSED_ZSTD is not set
# CONFIG_DEBUG_INFO_SPLIT is not set
# CONFIG_DEBUG_INFO_BTF is not set
CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
# CONFIG_GDB_SCRIPTS is not set
CONFIG_FRAME_WARN=2048
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_READABLE_ASM is not set
# CONFIG_HEADERS_INSTALL is not set
# CONFIG_DEBUG_SECTION_MISMATCH is not set
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set
CONFIG_OBJTOOL=y
# CONFIG_OBJTOOL_WERROR is not set
CONFIG_NOINSTR_VALIDATION=y
# CONFIG_VMLINUX_MAP is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# end of Compile-time checks and compiler options

#
# Generic Kernel Debugging Instruments
#
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_FS_ALLOW_ALL=y
# CONFIG_DEBUG_FS_ALLOW_NONE is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
CONFIG_ARCH_HAS_UBSAN=y
# CONFIG_UBSAN is not set
CONFIG_HAVE_ARCH_KCSAN=y
CONFIG_HAVE_KCSAN_COMPILER=y
# CONFIG_KCSAN is not set
# end of Generic Kernel Debugging Instruments

#
# Networking Debugging
#
CONFIG_NET_DEV_REFCNT_TRACKER=y
CONFIG_NET_NS_REFCNT_TRACKER=y
CONFIG_DEBUG_NET=y
# CONFIG_DEBUG_NET_SMALL_RTNL is not set
# end of Networking Debugging

#
# Memory Debugging
#
# CONFIG_PAGE_EXTENSION is not set
# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_PAGE_OWNER is not set
# CONFIG_PAGE_TABLE_CHECK is not set
# CONFIG_PAGE_POISONING is not set
# CONFIG_DEBUG_PAGE_REF is not set
# CONFIG_DEBUG_RODATA_TEST is not set
CONFIG_ARCH_HAS_DEBUG_WX=y
CONFIG_DEBUG_WX=y
CONFIG_ARCH_HAS_PTDUMP=y
CONFIG_PTDUMP=y
# CONFIG_PTDUMP_DEBUGFS is not set
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE=16000
# CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF is not set
# CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN is not set
# CONFIG_PER_VMA_LOCK_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SHRINKER_DEBUG is not set
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y
# CONFIG_DEBUG_VFS is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_VM_PGTABLE is not set
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
# CONFIG_DEBUG_VIRTUAL is not set
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_PER_CPU_MAPS is not set
CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y
# CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP is not set
# CONFIG_MEM_ALLOC_PROFILING is not set
CONFIG_HAVE_ARCH_KASAN=y
CONFIG_HAVE_ARCH_KASAN_VMALLOC=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CC_HAS_KASAN_SW_TAGS=y
CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
# CONFIG_KASAN is not set
CONFIG_HAVE_ARCH_KFENCE=y
# CONFIG_KFENCE is not set
CONFIG_HAVE_ARCH_KMSAN=y
# end of Memory Debugging

# CONFIG_DEBUG_SHIRQ is not set

#
# Debug Oops, Lockups and Hangs
#
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=86400
# CONFIG_SOFTLOCKUP_DETECTOR is not set
CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY=y
# CONFIG_HARDLOCKUP_DETECTOR is not set
CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y
# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_WQ_WATCHDOG is not set
# CONFIG_WQ_CPU_INTENSIVE_REPORT is not set
# CONFIG_TEST_LOCKUP is not set
# end of Debug Oops, Lockups and Hangs

#
# Scheduler Debugging
#
CONFIG_SCHED_INFO=y
CONFIG_SCHEDSTATS=y
# end of Scheduler Debugging

# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_DEBUG_ATOMIC is not set

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
CONFIG_LOCK_DEBUGGING_SUPPORT=y
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_DEBUG_ATOMIC_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_LOCK_TORTURE_TEST is not set
# CONFIG_WW_MUTEX_SELFTEST is not set
# CONFIG_SCF_TORTURE_TEST is not set
# CONFIG_CSD_LOCK_WAIT_DEBUG is not set
# end of Lock Debugging (spinlocks, mutexes, etc...)

CONFIG_NMI_CHECK_CPU=y
# CONFIG_DEBUG_IRQFLAGS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set

#
# Debug kernel data structures
#
CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PLIST=y
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_CLOSURES is not set
# CONFIG_DEBUG_MAPLE_TREE is not set
# end of Debug kernel data structures

#
# RCU Debugging
#
# CONFIG_RCU_SCALE_TEST is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_REF_SCALE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=100
CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0
# CONFIG_RCU_CPU_STALL_CPUTIME is not set
# CONFIG_RCU_TRACE is not set
# CONFIG_RCU_EQS_DEBUG is not set
# end of RCU Debugging

# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
# CONFIG_LATENCYTOP is not set
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_RETHOOK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_JMP=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_FENTRY=y
CONFIG_HAVE_OBJTOOL_MCOUNT=y
CONFIG_HAVE_OBJTOOL_NOP_MCOUNT=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y
CONFIG_TRACE_CLOCK=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_TRACEFS_AUTOMOUNT_DEPRECATED=y
# CONFIG_BOOTTIME_TRACING is not set
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_HWLAT_TRACER is not set
# CONFIG_OSNOISE_TRACER is not set
# CONFIG_TIMERLAT_TRACER is not set
# CONFIG_MMIOTRACE is not set
# CONFIG_FTRACE_SYSCALLS is not set
# CONFIG_TRACER_SNAPSHOT is not set
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_UPROBE_EVENTS=y
CONFIG_EPROBE_EVENTS=y
CONFIG_BPF_EVENTS=y
CONFIG_DYNAMIC_EVENTS=y
CONFIG_PROBE_EVENTS=y
# CONFIG_SYNTH_EVENTS is not set
# CONFIG_USER_EVENTS is not set
# CONFIG_HIST_TRIGGERS is not set
CONFIG_TRACE_EVENT_INJECT=y
# CONFIG_TRACEPOINT_BENCHMARK is not set
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_TRACE_EVAL_MAP_FILE is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_RING_BUFFER_STARTUP_TEST is not set
# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set
# CONFIG_RING_BUFFER_PERSISTENT_INJECT is not set
# CONFIG_PREEMPTIRQ_DELAY_TEST is not set
# CONFIG_RV is not set
# CONFIG_TRACE_REMOTE_TEST is not set
CONFIG_PROVIDE_OHCI1394_DMA_INIT=y
# CONFIG_SAMPLES is not set
CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y
CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
# CONFIG_STRICT_DEVMEM is not set

#
# x86 Debugging
#
CONFIG_EARLY_PRINTK_USB=y
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
CONFIG_EARLY_PRINTK_DBGP=y
# CONFIG_EARLY_PRINTK_USB_XDBC is not set
# CONFIG_DEBUG_TLBFLUSH is not set
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
# CONFIG_X86_DECODER_SELFTEST is not set
CONFIG_IO_DELAY_0X80=y
# CONFIG_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEBUG_BOOT_PARAMS=y
# CONFIG_CPA_DEBUG is not set
CONFIG_DEBUG_ENTRY=y
# CONFIG_DEBUG_NMI_SELFTEST is not set
CONFIG_X86_DEBUG_FPU=y
# CONFIG_PUNIT_ATOM_DEBUG is not set
CONFIG_UNWINDER_ORC=y
# CONFIG_UNWINDER_FRAME_POINTER is not set
# end of x86 Debugging

#
# Kernel Testing and Coverage
#
# CONFIG_KUNIT is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
CONFIG_FAULT_INJECTION=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAULT_INJECTION_USERCOPY=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_FUTEX=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
# CONFIG_FAIL_MMC_REQUEST is not set
# CONFIG_FAIL_SKB_REALLOC is not set
CONFIG_FAULT_INJECTION_CONFIGFS=y
# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set
CONFIG_ARCH_HAS_KCOV=y
CONFIG_KCOV=y
CONFIG_KCOV_ENABLE_COMPARISONS=y
CONFIG_KCOV_INSTRUMENT_ALL=y
CONFIG_KCOV_IRQ_AREA_SIZE=0x40000
# CONFIG_KCOV_SELFTEST is not set
CONFIG_RUNTIME_TESTING_MENU=y
# CONFIG_TEST_DHRY is not set
# CONFIG_LKDTM is not set
# CONFIG_TEST_DIV64 is not set
# CONFIG_TEST_MULDIV64 is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_TEST_REF_TRACKER is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_REED_SOLOMON_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
# CONFIG_PERCPU_TEST is not set
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_ASYNC_RAID6_TEST is not set
# CONFIG_TEST_HEXDUMP is not set
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_TEST_BITMAP is not set
# CONFIG_TEST_XARRAY is not set
# CONFIG_TEST_MAPLE_TREE is not set
# CONFIG_TEST_RHASHTABLE is not set
# CONFIG_TEST_IDA is not set
# CONFIG_TEST_LKM is not set
# CONFIG_TEST_BITOPS is not set
# CONFIG_TEST_VMALLOC is not set
# CONFIG_TEST_WORKQUEUE is not set
# CONFIG_TEST_BPF is not set
# CONFIG_FIND_BIT_BENCHMARK is not set
# CONFIG_TEST_FIRMWARE is not set
# CONFIG_TEST_SYSCTL is not set
# CONFIG_CONTEXT_ANALYSIS_TEST is not set
# CONFIG_TEST_UDELAY is not set
# CONFIG_TEST_STATIC_KEYS is not set
# CONFIG_TEST_KMOD is not set
# CONFIG_TEST_KALLSYMS is not set
# CONFIG_TEST_MEMCAT_P is not set
# CONFIG_TEST_MEMINIT is not set
# CONFIG_TEST_HMM is not set
# CONFIG_TEST_FREE_PAGES is not set
# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set
# CONFIG_TEST_OBJPOOL is not set
CONFIG_ARCH_USE_MEMTEST=y
# CONFIG_MEMTEST is not set
# end of Kernel Testing and Coverage

#
# Rust hacking
#
# end of Rust hacking
# end of Kernel hacking

CONFIG_IO_URING_ZCRX=y
CONFIG_IO_URING_BPF=y
KernelRepo git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
ReproCID 5266182317277184
ReproOpts
Show (143 bytes)
{"repeat":true,"procs":1,"slowdown":1,"sandbox":"","sandbox_arg":0,"leak":true,"close_fds":false,"sysctl":true,"segv":true,"callcomments":true}
ReproSyzID 4815937053655040
SyzkallerCommit 492bab153dea5e0e414bd0bbf60c3871267255ed
TargetArch amd64
TargetOS linux

Current Stage: moderation
Next Stage: upstream

Reporting Stages and Comments:
Stage Source Reported At Ext ID Comments
moderation lore 2026/07/30 15:12 <67862448-cd60-416f-b63f-bbd295ceeba1@mail.kernel.org>
1 Comments
  • syzbot@kernel.org (2026/07/30 15:14):
    When a USB function instance for midi2 is allocated, it dynamically
    allocates ep_opts and block_opts structures and adds them as default groups
    (ep.0 and block.0). While configfs removes the dentries for default groups
    when the parent directory is removed, it does not automatically drop their
    reference counts. This responsibility lies with the driver.
    
    Because f_midi2_free_inst() and f_midi2_ep_opts_release() do not clean up
    their default groups, the ep_opts and block_opts structures are leaked when
    the function instance is destroyed.
    
    Fix this by explicitly calling configfs_remove_default_groups() in the
    respective release functions. This ensures that the reference counts of the
    default groups are properly dropped, triggering the existing release
    callbacks (f_midi2_ep_opts_release and f_midi2_block_opts_release) to
    safely free the dynamically allocated memory.
    
    Kmemleak reports:
    
    BUG: memory leak
    unreferenced object 0xffff88810aacb200 (size 512):
      comm "syz.0.19", pid 6225, jiffies 4294944049
      hex dump (first 32 bytes):
        08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
        00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
      backtrace (crc f2efe6a4):
        ...
        f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504
        [inline]
        f_midi2_alloc_inst+0x80/0x2c0
        drivers/usb/gadget/function/f_midi2.c:2666
        ...
    
    BUG: memory leak
    unreferenced object 0xffff8881083d9e00 (size 256):
      comm "syz.0.19", pid 6225, jiffies 4294944049
      hex dump (first 32 bytes):
        08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
        00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
      backtrace (crc cc37bc9e):
        ...
        f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342
        [inline]
        f_midi2_alloc_inst+0x16a/0x2c0
        drivers/usb/gadget/function/f_midi2.c:2673
        ...
    
    Fixes: 29ee7a4dddd5 ("usb: gadget: midi2: Add configfs support")
    Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
    Reported-by: syzbot+eaa106d192c9daf37f95@syzkaller.appspotmail.com
    Closes: https://syzkaller.appspot.com/bug?extid=eaa106d192c9daf37f95
    Link: https://syzkaller.appspot.com/ai_job?id=9087164f-64c8-456d-abd0-052d4a7f1ddd
    To: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>
    To: <linux-usb@vger.kernel.org>
    To: "Takashi Iwai" <tiwai@suse.de>
    Cc: "Christophe JAILLET" <christophe.jaillet@wanadoo.fr>
    Cc: "Kees Cook" <kees@kernel.org>
    Cc: <linux-kernel@vger.kernel.org>
    
    ---
    diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
    index 19fdac024..ec4266ecc 100644
    --- a/drivers/usb/gadget/function/f_midi2.c
    +++ b/drivers/usb/gadget/function/f_midi2.c
    @@ -2473,6 +2473,7 @@ static void f_midi2_ep_opts_release(struct config_item *item)
     {
     	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
     
    +	configfs_remove_default_groups(to_config_group(item));
     	kfree(opts->info.ep_name);
     	kfree(opts->info.product_id);
     	kfree(opts);
    @@ -2639,6 +2640,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
     
     	opts = container_of(f, struct f_midi2_opts, func_inst);
     
    +	configfs_remove_default_groups(&opts->func_inst.group);
     	kfree(opts->info.iface_name);
     	kfree(opts);
     }
    
    
    base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff
    -- 
    This is an AI-generated patch subject to moderation.
    Reply with '#syz upstream' to Sign-off the patch as a human author
    and send it to the upstream kernel mailing lists.
    Reply with '#syz reject' to reject it ('#syz unreject' to undo).
    
    See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
    You can comment on the patch as usual, syzbot will try to address
    the comments and send a new version of the patch if necessary.
    syzbot engineers can be reached at syzkaller@googlegroups.com.
    

Outputs:
AckedBy
[]
Fixes
map[AuthorEmail:tiwai@suse.de AuthorName:Takashi Iwai Hash:29ee7a4dddd5caa18d1cef000f20c6af43f762f1 Title:usb: gadget: midi2: Add configfs support]
KernelBranch
master
KernelCommit
f5098b6bae761e346ebcd9da7f95622c04733cff
KernelRepo
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
PatchDescription
usb: gadget: midi2: Fix memory leak in configfs default groups

When a USB function instance for midi2 is allocated, it dynamically
allocates ep_opts and block_opts structures and adds them as default groups
(ep.0 and block.0). While configfs removes the dentries for default groups
when the parent directory is removed, it does not automatically drop their
reference counts. This responsibility lies with the driver.

Because f_midi2_free_inst() and f_midi2_ep_opts_release() do not clean up
their default groups, the ep_opts and block_opts structures are leaked when
the function instance is destroyed.

Fix this by explicitly calling configfs_remove_default_groups() in the
respective release functions. This ensures that the reference counts of the
default groups are properly dropped, triggering the existing release
callbacks (f_midi2_ep_opts_release and f_midi2_block_opts_release) to
safely free the dynamically allocated memory.

Kmemleak reports:

BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    ...
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504
    [inline]
    f_midi2_alloc_inst+0x80/0x2c0
    drivers/usb/gadget/function/f_midi2.c:2666
    ...

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    ...
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342
    [inline]
    f_midi2_alloc_inst+0x16a/0x2c0
    drivers/usb/gadget/function/f_midi2.c:2673
    ...
PatchDiff
diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2473,6 +2473,7 @@ static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
@@ -2639,6 +2640,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }
Recipients
[map[Email:christophe.jaillet@wanadoo.fr Name:Christophe JAILLET To:false] map[Email:gregkh@linuxfoundation.org Name:Greg Kroah-Hartman To:true] map[Email:kees@kernel.org Name:Kees Cook To:false] map[Email:linux-kernel@vger.kernel.org Name: To:false] map[Email:linux-usb@vger.kernel.org Name: To:true] map[Email:tiwai@suse.de Name:Takashi Iwai To:true]]
ReportedBy
[]
ReviewedBy
[]
TestedBy
[]

Crash report:
2026/07/26 12:12:48 executed programs: 5
BUG: memory leak
unreferenced object 0xffff888112a69c00 (size 512):
  comm "syz.0.19", pid 5954, jiffies 4294946869
  hex dump (first 32 bytes):
    08 9c a6 12 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc 56e62c00):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x356/0x440 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504 [inline]
    f_midi2_alloc_inst+0xa0/0x250 drivers/usb/gadget/function/f_midi2.c:2666
    try_get_usb_function_instance+0xb8/0x100 drivers/usb/gadget/functions.c:28
    usb_get_function_instance+0x16/0x70 drivers/usb/gadget/functions.c:44
    function_make+0xf5/0x240 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x2e9/0x6f0 fs/configfs/dir.c:1360
    vfs_mkdir+0x16c/0x3a0 fs/namei.c:5276
    filename_mkdirat+0x27c/0x300 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat fs/namei.c:5327 [inline]
    __x64_sys_mkdirat+0x39/0x60 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0xf8/0x610 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

BUG: memory leak
unreferenced object 0xffff8881105a3f00 (size 256):
  comm "syz.0.19", pid 5954, jiffies 4294946869
  hex dump (first 32 bytes):
    08 3f 5a 10 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  .?Z.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f7f284e3):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x356/0x440 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_block_opts_create+0x82/0x120 drivers/usb/gadget/function/f_midi2.c:2342
    f_midi2_alloc_inst+0xe9/0x250 drivers/usb/gadget/function/f_midi2.c:2673
    try_get_usb_function_instance+0xb8/0x100 drivers/usb/gadget/functions.c:28
    usb_get_function_instance+0x16/0x70 drivers/usb/gadget/functions.c:44
    function_make+0xf5/0x240 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x2e9/0x6f0 fs/configfs/dir.c:1360
    vfs_mkdir+0x16c/0x3a0 fs/namei.c:5276
    filename_mkdirat+0x27c/0x300 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat fs/namei.c:5327 [inline]
    __x64_sys_mkdirat+0x39/0x60 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0xf8/0x610 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF

Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/30 14:12 flow patching
59m Results:
map[AckedBy:[] Fixes:map[AuthorEmail:tiwai@suse.de AuthorName:Takashi Iwai Hash:29ee7a4dddd5caa18d1cef000f20c6af43f762f1 Title:usb: gadget: midi2: Add configfs support] KernelBranch:master KernelCommit:f5098b6bae761e346ebcd9da7f95622c04733cff KernelRepo:git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git PatchDescription:usb: gadget: midi2: Fix memory leak in configfs default groups

When a USB function instance for midi2 is allocated, it dynamically
allocates ep_opts and block_opts structures and adds them as default groups
(ep.0 and block.0). While configfs removes the dentries for default groups
when the parent directory is removed, it does not automatically drop their
reference counts. This responsibility lies with the driver.

Because f_midi2_free_inst() and f_midi2_ep_opts_release() do not clean up
their default groups, the ep_opts and block_opts structures are leaked when
the function instance is destroyed.

Fix this by explicitly calling configfs_remove_default_groups() in the
respective release functions. This ensures that the reference counts of the
default groups are properly dropped, triggering the existing release
callbacks (f_midi2_ep_opts_release and f_midi2_block_opts_release) to
safely free the dynamically allocated memory.

Kmemleak reports:

BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    ...
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504
    [inline]
    f_midi2_alloc_inst+0x80/0x2c0
    drivers/usb/gadget/function/f_midi2.c:2666
    ...

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    ...
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342
    [inline]
    f_midi2_alloc_inst+0x16a/0x2c0
    drivers/usb/gadget/function/f_midi2.c:2673
    ... PatchDiff:diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2473,6 +2473,7 @@ static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
@@ -2639,6 +2640,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 Recipients:[map[Email:christophe.jaillet@wanadoo.fr Name:Christophe JAILLET To:false] map[Email:gregkh@linuxfoundation.org Name:Greg Kroah-Hartman To:true] map[Email:kees@kernel.org Name:Kees Cook To:false] map[Email:linux-kernel@vger.kernel.org Name: To:false] map[Email:linux-usb@vger.kernel.org Name: To:true] map[Email:tiwai@suse.de Name:Takashi Iwai To:true]] ReportedBy:[] ReviewedBy:[] TestedBy:[]]

1/1 2026/07/30 14:12 action base-commit-picker
0m Results:
map[KernelBranch:master KernelCommit:f5098b6bae761e346ebcd9da7f95622c04733cff KernelRepo:git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git]

2/1 2026/07/30 14:12 action syz-repro-to-c-repro
0m Results:
map[SimplifiedCRepro:// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE 

#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
		syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
	syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
	syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
	const char* reason;
	(void)reason;
				if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
//  mkdirat arguments: [
//    fd: fd_dir (resource)
//    path: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 00} (length 0xe)
//    }
//    mode: open_mode = 0x1ff (8 bytes)
//  ]
memcpy((void*)0x200000000080, "./my_configfs\000", 14);
	syscall(__NR_mkdirat, /*fd=*/0xffffff9c, /*path=*/0x200000000080ul, /*mode=S_IXOTH|S_IWOTH|S_IROTH|S_IXGRP|S_IWGRP|S_IRGRP|S_IXUSR|S_IWUSR|0x100*/0x1fful);
//  mount arguments: [
//    src: nil
//    dst: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 00} (length 0xe)
//    }
//    type: ptr[in, buffer] {
//      buffer: {63 6f 6e 66 69 67 66 73 00} (length 0x9)
//    }
//    flags: mount_flags = 0x0 (8 bytes)
//    data: nil
//  ]
memcpy((void*)0x200000000100, "./my_configfs\000", 14);
memcpy((void*)0x200000000140, "configfs\000", 9);
	syscall(__NR_mount, /*src=*/0ul, /*dst=*/0x200000000100ul, /*type=*/0x200000000140ul, /*flags=*/0ul, /*data=*/0ul);
//  mkdirat arguments: [
//    fd: fd_dir (resource)
//    path: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 2f 75 73 62 5f 67 61 64 67 65 74 2f 67 31 00} (length 0x1c)
//    }
//    mode: open_mode = 0x1ff (8 bytes)
//  ]
memcpy((void*)0x200000000180, "./my_configfs/usb_gadget/g1\000", 28);
	syscall(__NR_mkdirat, /*fd=*/0xffffff9c, /*path=*/0x200000000180ul, /*mode=S_IXOTH|S_IWOTH|S_IROTH|S_IXGRP|S_IWGRP|S_IRGRP|S_IXUSR|S_IWUSR|0x100*/0x1fful);
//  mkdirat arguments: [
//    fd: fd_dir (resource)
//    path: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 2f 75 73 62 5f 67 61 64 67 65 74 2f 67 31 2f 66 75 6e 63 74 69 6f 6e 73 2f 6d 69 64 69 32 2e 75 73 62 30 00} (length 0x31)
//    }
//    mode: open_mode = 0x1ff (8 bytes)
//  ]
memcpy((void*)0x200000000200, "./my_configfs/usb_gadget/g1/functions/midi2.usb0\000", 49);
	syscall(__NR_mkdirat, /*fd=*/0xffffff9c, /*path=*/0x200000000200ul, /*mode=S_IXOTH|S_IWOTH|S_IROTH|S_IXGRP|S_IWGRP|S_IRGRP|S_IXUSR|S_IWUSR|0x100*/0x1fful);
//  rmdir arguments: [
//    path: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 2f 75 73 62 5f 67 61 64 67 65 74 2f 67 31 2f 66 75 6e 63 74 69 6f 6e 73 2f 6d 69 64 69 32 2e 75 73 62 30 00} (length 0x31)
//    }
//  ]
memcpy((void*)0x200000000300, "./my_configfs/usb_gadget/g1/functions/midi2.usb0\000", 49);
	syscall(__NR_rmdir, /*path=*/0x200000000300ul);
	return 0;
}
]

3/1 2026/07/30 14:12 action kernel-checkouter
0m Results:
map[KernelSrc:/app/workdir/cache/src/3735123449433f9e6f9fb5b55ddd9994cbcf15f0]

4/1 2026/07/30 14:12 action kernel-builder
0m Results:
map[KernelObj:/app/workdir/cache/build/f2406aa8130f610795c291eecb3c31a15ab218ca]

5/1 2026/07/30 14:12 action crash-reproducer
0m Results:
map[OtherCrashReports:<nil> ReproducedBugTitle:memory leak in usb_get_function_instance ReproducedCrashReport:2026/07/30 13:30:35 executed programs: 5
BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504 [inline]
    f_midi2_alloc_inst+0x80/0x2c0 drivers/usb/gadget/function/f_midi2.c:2666
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342 [inline]
    f_midi2_alloc_inst+0x16a/0x2c0 drivers/usb/gadget/function/f_midi2.c:2673
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF
 ReproducedFaultInjection:]

6/1 2026/07/30 14:12 action codesearch-prepare
0m Results:
map[Index:codesearch-index]

7/1 2026/07/30 14:12 agent debugger
0m Model:
best-expensive

Instruction:
You are an experienced Linux kernel developer tasked with debugging a kernel crash root cause.
You need to provide a detailed explanation of the root cause for another developer to be
able to write a fix for the bug based on your explanation. Include all relevant details
into the response: function/struct/field/etc names, code snippets, line numbers,
macro/enum values, etc.



Don't make assumptions about the kernel source code (it may be different from what you assume it is).
Extensively use the provided code access tools (codesearch-*, git-*, grepper, etc)
to examine the actual source code, and confirm any assumptions.

Prefer calling several tools at the same time to save round-trips.

Prompt:
The crash is:

2026/07/30 13:30:35 executed programs: 5
BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504 [inline]
    f_midi2_alloc_inst+0x80/0x2c0 drivers/usb/gadget/function/f_midi2.c:2666
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342 [inline]
    f_midi2_alloc_inst+0x16a/0x2c0 drivers/usb/gadget/function/f_midi2.c:2673
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF


The following C code is a draft of the vulnerable syscall sequence. Keep in mind that
it may lack the precise threading, sandboxing, and some arguments of a working reproducer:

// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE 

#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
		syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
	syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
	syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
	const char* reason;
	(void)reason;
				if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
//  mkdirat arguments: [
//    fd: fd_dir (resource)
//    path: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 00} (length 0xe)
//    }
//    mode: open_mode = 0x1ff (8 bytes)
//  ]
memcpy((void*)0x200000000080, "./my_configfs\000", 14);
	syscall(__NR_mkdirat, /*fd=*/0xffffff9c, /*path=*/0x200000000080ul, /*mode=S_IXOTH|S_IWOTH|S_IROTH|S_IXGRP|S_IWGRP|S_IRGRP|S_IXUSR|S_IWUSR|0x100*/0x1fful);
//  mount arguments: [
//    src: nil
//    dst: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 00} (length 0xe)
//    }
//    type: ptr[in, buffer] {
//      buffer: {63 6f 6e 66 69 67 66 73 00} (length 0x9)
//    }
//    flags: mount_flags = 0x0 (8 bytes)
//    data: nil
//  ]
memcpy((void*)0x200000000100, "./my_configfs\000", 14);
memcpy((void*)0x200000000140, "configfs\000", 9);
	syscall(__NR_mount, /*src=*/0ul, /*dst=*/0x200000000100ul, /*type=*/0x200000000140ul, /*flags=*/0ul, /*data=*/0ul);
//  mkdirat arguments: [
//    fd: fd_dir (resource)
//    path: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 2f 75 73 62 5f 67 61 64 67 65 74 2f 67 31 00} (length 0x1c)
//    }
//    mode: open_mode = 0x1ff (8 bytes)
//  ]
memcpy((void*)0x200000000180, "./my_configfs/usb_gadget/g1\000", 28);
	syscall(__NR_mkdirat, /*fd=*/0xffffff9c, /*path=*/0x200000000180ul, /*mode=S_IXOTH|S_IWOTH|S_IROTH|S_IXGRP|S_IWGRP|S_IRGRP|S_IXUSR|S_IWUSR|0x100*/0x1fful);
//  mkdirat arguments: [
//    fd: fd_dir (resource)
//    path: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 2f 75 73 62 5f 67 61 64 67 65 74 2f 67 31 2f 66 75 6e 63 74 69 6f 6e 73 2f 6d 69 64 69 32 2e 75 73 62 30 00} (length 0x31)
//    }
//    mode: open_mode = 0x1ff (8 bytes)
//  ]
memcpy((void*)0x200000000200, "./my_configfs/usb_gadget/g1/functions/midi2.usb0\000", 49);
	syscall(__NR_mkdirat, /*fd=*/0xffffff9c, /*path=*/0x200000000200ul, /*mode=S_IXOTH|S_IWOTH|S_IROTH|S_IXGRP|S_IWGRP|S_IRGRP|S_IXUSR|S_IWUSR|0x100*/0x1fful);
//  rmdir arguments: [
//    path: ptr[in, buffer] {
//      buffer: {2e 2f 6d 79 5f 63 6f 6e 66 69 67 66 73 2f 75 73 62 5f 67 61 64 67 65 74 2f 67 31 2f 66 75 6e 63 74 69 6f 6e 73 2f 6d 69 64 69 32 2e 75 73 62 30 00} (length 0x31)
//    }
//  ]
memcpy((void*)0x200000000300, "./my_configfs/usb_gadget/g1/functions/midi2.usb0\000", 49);
	syscall(__NR_rmdir, /*path=*/0x200000000300ul);
	return 0;
}





Reply:
The root cause of this memory leak is that the driver fails to drop the reference counts of its default configfs groups when the parent group is destroyed.

When a USB function instance for `midi2` is allocated via `f_midi2_alloc_inst()`, it dynamically allocates `ep_opts` and `block_opts` structures using `kzalloc_obj()`. These structures are then initialized as configfs groups and added as default groups to their respective parents:
- `ep.0` is added as a default group to the function instance group (`opts->func_inst.group`).
- `block.0` is added as a default group to the endpoint group (`ep_opts->group`).

When the user removes the configfs directory for the function instance (via `rmdir`), configfs removes the dentries for the default groups but **does not** automatically drop their reference counts. The responsibility of dropping the refcounts of default groups lies with the driver, typically by calling `configfs_remove_default_groups()` when the parent group is released.

However, `f_midi2_free_inst()` (which is called when the function instance's refcount reaches 0) only frees the `f_midi2_opts` structure and does not clean up its default groups. Similarly, `f_midi2_ep_opts_release()` does not clean up its default groups. As a result, the `ep_opts` and `block_opts` structures are leaked.

### How to fix it

To fix the leak, you need to explicitly remove the default groups and drop their reference counts before freeing the parent structures. This can be done by calling `configfs_remove_default_groups()` in the respective release functions.

1. In `f_midi2_free_inst()`, drop the default groups of the function instance (this will drop the refcount of `ep.0` and trigger `f_midi2_ep_opts_release`):
```c
static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group); /* ADD THIS */
	kfree(opts->info.iface_name);
	kfree(opts);
}
```

2. In `f_midi2_ep_opts_release()`, drop the default groups of the endpoint (this will drop the refcount of `block.0` and trigger `f_midi2_block_opts_release`):
```c
static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item)); /* ADD THIS */
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
}
```

With these changes, the hierarchy of default groups will be properly unrolled and freed when the function instance is destroyed, whether it's through configfs `rmdir` or an error path that directly calls `usb_put_function_instance()`.

8/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 7137
							output: 26
							thoughts: 121
						

Thoughts:
**Investigating a Memory Leak in the MIDI2 USB Gadget Driver**

Okay, so I've got a memory leak to track down. It seems like we've got a problem with the `f_midi2_ep_opts_create` and `f_midi2_block_opts_create` functions in `drivers/usb/gadget/function/f_midi2.c`. The leak is specifically triggered when a USB function instance of type "midi2" is created and then deleted. The reproducer sets up a configfs directory for `midi2.usb0` and then promptly tears it down.

My gut tells me that the issue likely originates within the instantiation code, so let's start by digging into `f_midi2_alloc_inst` within that same file, `drivers/usb/gadget/function/f_midi2.c`. Time to see what's happening under the hood. Hopefully, I can spot the missed resource allocation or deallocation.



9/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_alloc_inst]

Results:
map[SourceCode:2646:	/* gadget alloc_inst */
2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
2655:		if (!opts)
2656:			return ERR_PTR(-ENOMEM);
2657:	
2658:		mutex_init(&opts->lock);
2659:		opts->func_inst.free_func_inst = f_midi2_free_inst;
2660:		opts->info.process_ump = true;
2661:		opts->info.static_block = true;
2662:		opts->info.num_reqs = 32;
2663:		opts->info.req_buf_size = 512;
2664:	
2665:		/* create the default ep */
2666:		ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
2667:		if (ret) {
2668:			kfree(opts);
2669:			return ERR_PTR(ret);
2670:		}
2671:	
2672:		/* create the default block */
2673:		ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
2674:		if (ret) {
2675:			kfree(ep_opts);
2676:			kfree(opts);
2677:			return ERR_PTR(ret);
2678:		}
2679:	
2680:		/* set up the default MIDI1 (that is mandatory) */
2681:		block_opts->info.midi1_num_groups = 1;
2682:	
2683:		config_group_init_type_name(&opts->func_inst.group, "",
2684:					    &f_midi2_func_type);
2685:	
2686:		config_group_init_type_name(&ep_opts->group, "ep.0",
2687:					    &f_midi2_ep_type);
2688:		configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
2689:	
2690:		config_group_init_type_name(&block_opts->group, "block.0",
2691:					    &f_midi2_block_type);
2692:		configfs_add_default_group(&block_opts->group, &ep_opts->group);
2693:	
2694:		return &opts->func_inst;
2695:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

10/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 8330
							output: 26
							thoughts: 23
						

Thoughts:
Here's my take on the problem:

**Root Cause Analysis - Memory Leak in Instance Deallocation**

Okay, so we've got a memory leak, and it's rearing its ugly head during instance deallocation. That immediately narrows the focus. If the leak were happening at any other time, I'd have a much wider search space. But since it's when the instance is being freed, that tells me the problem lies within the freeing process itself. My gut says let's zero in on `f_midi2_free_inst`. That function is the likely culprit. It's the point of contact, the last chance to clean up before the memory is released back to the system. Now I need to dive into the implementation of that function with a fine-toothed comb to see what's being missed or improperly handled. Gotta start with the code and see what it's doing with all the instance memory.



11/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_free_inst]

Results:
map[SourceCode:2636:	static void f_midi2_free_inst(struct usb_function_instance *f)
2637:	{
2638:		struct f_midi2_opts *opts;
2639:	
2640:		opts = container_of(f, struct f_midi2_opts, func_inst);
2641:	
2642:		kfree(opts->info.iface_name);
2643:		kfree(opts);
2644:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

12/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 8744
							output: 28
							thoughts: 127
						

Thoughts:
**Analyzing MIDI Gadget Instance Management**

Okay, so `f_midi2_free_inst` is pretty straightforward – it's just responsible for cleaning up memory. Specifically, it frees `opts->info.iface_name` and the `opts` structure itself. No surprises there. But, looking at the setup side, `f_midi2_alloc_inst` is where the interesting stuff happens. It's the one responsible for creating those `ep_opts` and `block_opts` structures. Ah, and I see those are created using `f_midi2_ep_opts_create` and `f_midi2_block_opts_create`. Those functions are probably crucial to understanding how the configfs groups are constructed. Definitely need to dive into `f_midi2_ep_opts_create` and `f_midi2_block_opts_create` to fully grasp the implementation.



13/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_ep_opts_create]

Results:
map[SourceCode:2497:	/* create a f_midi2_ep_opts instance */
2498:	static int f_midi2_ep_opts_create(struct f_midi2_opts *opts,
2499:					  unsigned int index,
2500:					  struct f_midi2_ep_opts **ep_p)
2501:	{
2502:		struct f_midi2_ep_opts *ep_opts;
2503:	
2504:		ep_opts = kzalloc_obj(*ep_opts);
2505:		if (!ep_opts)
2506:			return -ENOMEM;
2507:	
2508:		ep_opts->opts = opts;
2509:		ep_opts->index = index;
2510:	
2511:		/* set up the default values */
2512:		ep_opts->info.protocol = 2;
2513:		ep_opts->info.protocol_caps = 3;
2514:	
2515:		opts->eps[index] = ep_opts;
2516:		*ep_p = ep_opts;
2517:		return 0;
2518:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

14/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 9454
							output: 28
							thoughts: 13
						

Thoughts:
Okay, here's my interpretation of that thought process, assuming I'm an expert in MIDI processing and likely dealing with embedded systems or a similar constrained environment.

**My Analysis of `f_midi2_block_opts_create`**

Alright, so I see `f_midi2_block_opts_create`. This function name immediately suggests we're in the realm of creating options or parameters related to a MIDI 2.0 processing block. Given my experience, I'm already mentally running through the typical MIDI 2.0 data structures and processing requirements. I'm thinking about the common use cases: maybe this is setting up parameters for a filter, a generator, or some kind of real-time transformation on MIDI 2.0 data streams.

I'm focusing on the "block" aspect. That implies a modular design, probably for real-time applications where we're linking these "blocks" together to form a processing pipeline. Efficiency is key here. Memory allocation is a primary concern. The "_opts" suffix tells me this isn't the core of the function but more likely related to customization, allowing a user (or another part of the system) to tailor the operation of this processing block.

Now, I'm thinking about what kinds of options we might need to configure. Is this about setting buffer sizes, data format specifics (like 7-bit vs. 16-bit encoding, channel numbering schemes), control message ranges, clock divider, error handling behavior, perhaps interrupt enable flags if it's tightly coupled with hardware. Is it about choosing between different processing algorithms that the block implements? Does it support different input and output MIDI formats?

I'm guessing this function likely returns a handle or pointer to a data structure (or a struct) that holds all these option parameters. That's a common pattern for configuration routines. I'm also wondering if it has any associated functions for validation (to ensure option values are valid) and destruction (to free the memory allocated by the options structure). I'll need to dig into the function's definition and usage context to flesh out these assumptions.



15/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_block_opts_create]

Results:
map[SourceCode:2328:	/* create a f_midi2_block_opts instance for the given block number */
2329:	static int f_midi2_block_opts_create(struct f_midi2_ep_opts *ep_opts,
2330:					     unsigned int blk,
2331:					     struct f_midi2_block_opts **block_p)
2332:	{
2333:		struct f_midi2_block_opts *block_opts;
2334:		int ret = 0;
2335:	
2336:		mutex_lock(&ep_opts->opts->lock);
2337:		if (ep_opts->opts->refcnt || ep_opts->blks[blk]) {
2338:			ret = -EBUSY;
2339:			goto out;
2340:		}
2341:	
2342:		block_opts = kzalloc_obj(*block_opts);
2343:		if (!block_opts) {
2344:			ret = -ENOMEM;
2345:			goto out;
2346:		}
2347:	
2348:		block_opts->ep = ep_opts;
2349:		block_opts->id = blk;
2350:	
2351:		/* set up the default values */
2352:		block_opts->info.direction = SNDRV_UMP_DIR_BIDIRECTION;
2353:		block_opts->info.first_group = 0;
2354:		block_opts->info.num_groups = 1;
2355:		block_opts->info.ui_hint = SNDRV_UMP_BLOCK_UI_HINT_BOTH;
2356:		block_opts->info.active = 1;
2357:	
2358:		ep_opts->blks[blk] = block_opts;
2359:		*block_p = block_opts;
2360:	
2361:	 out:
2362:		mutex_unlock(&ep_opts->opts->lock);
2363:		return ret;
2364:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

16/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 10545
							output: 28
							thoughts: 62
						

Thoughts:
**Examining ConfigFS Group Handling**

Okay, hold on a second. I need to make sure I understand this correctly. `ep_opts` and `block_opts`... those are defined as configfs groups, aren't they? That's right, they are. Now the critical question pops up – when the configfs directory containing those groups gets removed, does the system automatically free those resources? I'm betting that's handled by the configfs machinery, but I need to confirm. Let's dig into the details and make sure. Let me go back and double-check those release functions – specifically, `f_midi2_ep_opts_release` and `f_midi2_block_opts_release`. Those should reveal the freeing process for these configfs groups. I need to be absolutely certain we are releasing these resources properly.



17/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_ep_opts_release]

Results:
map[SourceCode:2472:	static void f_midi2_ep_opts_release(struct config_item *item)
2473:	{
2474:		struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
2475:	
2476:		kfree(opts->info.ep_name);
2477:		kfree(opts->info.product_id);
2478:		kfree(opts);
2479:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

18/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 10984
							output: 28
							thoughts: 13
						

Thoughts:
Okay, here's my interpretation of that thought process, summarized as you requested, in the first person, and assuming I'm an expert in this domain:

**My Immediate Assessment: `f_midi2_block_opts_release`**

Alright, so the focus is immediately zeroing in on `f_midi2_block_opts_release`. This likely means we're dealing with a function or process related to MIDI 2.0 block options, and specifically, the "release" aspect. My expert understanding tells me this is probably concerned with freeing up memory or resources associated with a block of MIDI data that's no longer needed, maybe at the end of a message, or after a specific block processing step.

My initial thoughts are:

*   **Memory Management is Critical:** The use of "release" implies a dynamic allocation of memory or some resource. I need to understand what's being released. Is this raw memory, handles to hardware, some internal data structure? Improper release leads to memory leaks or resource exhaustion, both potentially disastrous in a real-time MIDI system. I'm already anticipating the potential use of `free()`, `delete`, or similar deallocation methods.
*   **Context Matters:** The function name alone gives little information. I need to understand what context this release operation occurs within. Is it part of a larger MIDI parser, a specific MIDI block processing pipeline, or something else entirely? The surrounding code is key to understanding its purpose. I'll need to look at how the memory or resources were allocated to understand the proper release procedure.
*   **Error Handling and Safety:** Given that we're talking about releasing, I need to know about error handling. What happens if the release fails? Does the system gracefully degrade, or does it crash? Are there checks for null pointers or invalid handles before trying to free resources? Robustness is essential in a real-time audio environment.
*   **Concurrency:** If this is a multi-threaded system, I need to be concerned with thread safety. Is there any potential for race conditions where multiple threads could be attempting to access and release the same resources simultaneously? I'll be looking for mutexes, semaphores, or other synchronization primitives to protect the release operation.
*   **Documentation Check:** I'll also be expecting documentation, of course. Well-written code will come with clear explanations of its purpose, usage, and any assumptions it makes. I hope there's details about the parameters that are passed into the function.

In short, my mind is already starting to probe for potential pitfalls: memory leaks, resource exhaustion, thread safety issues, and the overall reliability of the release mechanism in this MIDI 2.0 context. It's time to dig deeper into the surrounding code and documentation.



19/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_block_opts_release]

Results:
map[SourceCode:2310:	static void f_midi2_block_opts_release(struct config_item *item)
2311:	{
2312:		struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
2313:	
2314:		kfree(opts->info.name);
2315:		kfree(opts);
2316:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

20/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 11754
							output: 26
							thoughts: 296
						

Thoughts:
**Understanding ConfigFS Group Management in MIDI2 Driver**

Okay, so I'm digging into this MIDI2 driver code and trying to grasp how the ConfigFS items are handled, specifically their lifetime. I'm seeing that when these ConfigFS items are released, they're freed. Makes sense. But here's where it gets interesting. In `f_midi2_alloc_inst`, I see these `ep_opts` and `block_opts` are added as *default* groups. The code block clearly shows the initialization and addition:

```c
	config_group_init_type_name(&opts->func_inst.group, "",
				    &f_midi2_func_type);

	config_group_init_type_name(&ep_opts->group, "ep.0",
				    &f_midi2_ep_type);
	configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);

	config_group_init_type_name(&block_opts->group, "block.0",
				    &f_midi2_block_type);
	configfs_add_default_group(&block_opts->group, &ep_opts->group);
```

My initial thought was, if they are default groups, then ConfigFS should manage their lifecycle in conjunction with the parent group, right? It seems logical. But then I quickly realized that's probably not the entire story. It's more likely that `configfs_add_default_group` adds them to the parent's `default_groups` list, indicating some kind of relationship, but not necessarily a direct reference. But does `configfs_add_default_group` actually *take* a reference, or is it just adding a pointer? That's what I need to clarify. I need to understand how the default groups are freed and if there's any memory management aspect that is critical to get right. Time to check the `configfs_add_default_group` function itself and how these default groups are released. That should clear this up.



21/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_add_default_group]

Results:
map[SourceCode: 109:	static inline void configfs_add_default_group(struct config_group *new_group,
 110:			struct config_group *group)
 111:	{
 112:		list_add_tail(&new_group->group_entry, &group->default_groups);
 113:	}
 SourceFile:include/linux/configfs.h]

22/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 12650
							output: 26
							thoughts: 31
						

Thoughts:
Here's my take on those thoughts:

**Analyzing Group Release Behavior in MIDI2**

Okay, so I'm thinking about how MIDI2 handles group releases. Specifically, when a parent group is freed, does that automatically cascade down and release all the child/default groups associated with it? I need to clarify that behavior, which is a critical aspect of memory management in this context. It's really easy to get leaks if there's any ambiguity in how these hierarchical structures are cleaned up.

Let me refresh my memory on that `f_midi2_free_inst` function again, as I suspect that's where the core logic for group deallocation resides. Gotta make sure I'm crystal clear on exactly how it handles the parent-child relationships and whether it recursively frees the defaults. I know a careful look through the source code will give me the answer.



23/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_free_inst]

Results:
map[SourceCode:2636:	static void f_midi2_free_inst(struct usb_function_instance *f)
2637:	{
2638:		struct f_midi2_opts *opts;
2639:	
2640:		opts = container_of(f, struct f_midi2_opts, func_inst);
2641:	
2642:		kfree(opts->info.iface_name);
2643:		kfree(opts);
2644:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

24/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 13059
							output: 21
							thoughts: 99
						

Thoughts:
**Delving into USB Gadget Function Instance Release**

Okay, so I'm thinking through this USB gadget code. I need to understand how function instances are cleaned up.  Hang on, `f_midi2_free_inst` - that's called when a `usb_function_instance` is released, right?  But hold on... `opts->func_inst.group` is a `config_group`! That's a ConfigFS thing.  So, the `usb_function_instance` and the ConfigFS structure are entangled.

My brain's telling me to trace the removal of the ConfigFS directory.  When a directory goes poof in ConfigFS, `configfs_rmdir` gets called.  Now I need to connect the dots. I need to either examine `configfs_rmdir` itself, or figure out how the USB gadget subsystem handles function instance release within that context.  Let's jump into `drivers/usb/gadget/configfs.c` and figure this out. I'm sure the answer lies there.



25/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:function_make]

Results:
map[SourceCode: 601:	static struct config_group *function_make(
 602:			struct config_group *group,
 603:			const char *name)
 604:	{
 605:		struct gadget_info *gi;
 606:		struct usb_function_instance *fi;
 607:		char buf[MAX_NAME_LEN];
 608:		char *func_name;
 609:		char *instance_name;
 610:		int ret;
 611:	
 612:		if (strlen(name) >= MAX_NAME_LEN)
 613:			return ERR_PTR(-ENAMETOOLONG);
 614:	
 615:		scnprintf(buf, MAX_NAME_LEN, "%s", name);
 616:	
 617:		func_name = buf;
 618:		instance_name = strchr(func_name, '.');
 619:		if (!instance_name) {
 620:			pr_err("Unable to locate . in FUNC.INSTANCE\n");
 621:			return ERR_PTR(-EINVAL);
 622:		}
 623:		*instance_name = '\0';
 624:		instance_name++;
 625:	
 626:		fi = usb_get_function_instance(func_name);
 627:		if (IS_ERR(fi))
 628:			return ERR_CAST(fi);
 629:	
 630:		ret = config_item_set_name(&fi->group.cg_item, "%s", name);
 631:		if (ret) {
 632:			usb_put_function_instance(fi);
 633:			return ERR_PTR(ret);
 634:		}
 635:		if (fi->set_inst_name) {
 636:			ret = fi->set_inst_name(fi, instance_name);
 637:			if (ret) {
 638:				usb_put_function_instance(fi);
 639:				return ERR_PTR(ret);
 640:			}
 641:		}
 642:	
 643:		gi = container_of(group, struct gadget_info, functions_group);
 644:	
 645:		mutex_lock(&gi->lock);
 646:		list_add_tail(&fi->cfs_list, &gi->available_func);
 647:		mutex_unlock(&gi->lock);
 648:		return &fi->group;
 649:	}
 SourceFile:drivers/usb/gadget/configfs.c]

26/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 14136
							output: 21
							thoughts: 14
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:

**My Line of Reasoning: Directory Removal and Function Dropping**

Alright, so the core trigger is a directory being deleted. That action immediately kicks off my internal process to execute `function_drop`. I'm assuming here that `function_drop` is specifically designed to handle the cleanup and necessary operations tied to the lifecycle of this directory. It's almost certainly more than just a direct "drop" in the SQL sense, but a well defined, perhaps multi-step procedure.

Given my understanding of similar systems, my mind immediately jumps to a few key areas that `function_drop` likely addresses:

*   **Dependency Management:** I'm assuming this directory held dependencies or relationships with other parts of the system or data store. `Function_drop` must ensure that any associated data, references, or links are updated, removed, or gracefully handled to maintain data integrity and consistency. Think cascading deletes, reference counting, dependency tracking, or metadata updates – I need to be *certain* that nothing gets orphaned or corrupted.
*   **Resource Cleanup:** A directory's removal is not simple. It's very likely that this directory held resources of some kind that now need to be released. These may include file handles, memory allocations, database connections, or other system resources. Efficient resource cleanup is critical to prevent leaks or degraded performance.
*   **Metadata Consistency:** The system's overall metadata *must* reflect the fact that the directory no longer exists. This probably involves updates to internal catalogs, indices, configuration files, and any other systems that track this directory's presence.
*   **Error Handling and Rollback:** There needs to be a robust strategy for handling failures within `function_drop`. What happens if a step fails? Can the process be rolled back, partially completed, or does it leave things in an inconsistent state? Proper error logging and exception handling are paramount. I need to be able to trust this function to clean up correctly, every time.
*   **Concurrency and Locking:** If multiple processes or threads can interact with this directory or related resources, `function_drop` will almost certainly have to employ some form of locking or synchronization to ensure atomicity and prevent race conditions. The degree of concurrency control is what I need to understand next.

In summary, when I see "directory removed, `function_drop` called," my thought process begins to dive into a detailed examination of what the system expects to happen. And I know the implication is an important cleanup operation with potentially significant consequences for data integrity and system stability.



27/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:function_drop]

Results:
map[SourceCode: 651:	static void function_drop(
 652:			struct config_group *group,
 653:			struct config_item *item)
 654:	{
 655:		struct usb_function_instance *fi = to_usb_function_instance(item);
 656:		struct gadget_info *gi;
 657:	
 658:		gi = container_of(group, struct gadget_info, functions_group);
 659:	
 660:		mutex_lock(&gi->lock);
 661:		list_del(&fi->cfs_list);
 662:		mutex_unlock(&gi->lock);
 663:		config_item_put(item);
 664:	}
 SourceFile:drivers/usb/gadget/configfs.c]

28/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 14954
							output: 26
							thoughts: 145
						

Thoughts:
**Delving into the `config_item_put` Process**

Okay, so I need to trace the lifecycle of a `config_item`. Specifically, I'm trying to understand how `config_item_put(item)` eventually leads to the release of resources associated with a `usb_function_instance`. I recall that the ultimate release happens through a specific function tied to the item. In the case of a `usb_function_instance`, I'm guessing it's something like `usb_function_instance_release` – or at least, that's what I'd expect.

Now, the piece I'm focusing on is how this connection is made. I see that `fi->group.cg_item` is relevant here, it has a type, and I need to figure out how it’s set. My mind jumps to the allocation code. Let's see... Ah, there it is! In `f_midi2_alloc_inst`, I see:

```c
	config_group_init_type_name(&opts->func_inst.group, "",
				    &f_midi2_func_type);
```

This is where the link happens! `config_group_init_type_name` is key. And that means I now need to understand what `f_midi2_func_type` is. It will define the release function and other characteristics of the `config_item`. I'll examine that next.



29/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_func_type]

Results:
map[SourceCode:2629:	static const struct config_item_type f_midi2_func_type = {
2630:		.ct_item_ops	= &f_midi2_item_ops,
2631:		.ct_group_ops	= &f_midi2_group_ops,
2632:		.ct_attrs	= f_midi2_attrs,
2633:		.ct_owner	= THIS_MODULE,
2634:	};
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

30/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 15598
							output: 26
							thoughts: 11
						

Thoughts:
Okay, here's my interpretation of those thoughts, crafted with the understanding that I'm speaking to a fellow expert:

**Delving into MIDI Item Operations**

Alright, let's break down this `f_midi2_item_ops` function. Immediately, I'm thinking about the low-level MIDI data structures involved. Specifically, I imagine this deals with the fundamental manipulation of MIDI item events – perhaps insertion, deletion, modification, time-stretching, quantization, and the like, all the core operations one needs for serious MIDI editing. I'm assuming it handles the underlying data, probably dealing with the bitwise manipulation of MIDI messages efficiently. Is it optimized for specific hardware? Is it designed to be threading-friendly? We'll have to consider those aspects when we review the code. The main question on my mind is: Does this implementation provide sufficient flexibility for the wide range of use cases we need to support in this project?



31/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_item_ops]

Results:
map[SourceCode:2620:	static const struct configfs_item_operations f_midi2_item_ops = {
2621:		.release	= f_midi2_opts_release,
2622:	};
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

32/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 15924
							output: 26
							thoughts: 11
						

Thoughts:
Okay, here's my summary, in the first person, as an expert in the field would perceive the thought process:

**Diving into `f_midi2_opts_release`**

Alright, let's dissect this. "And `f_midi2_opts_release`"... my initial thought is, "Okay, this is about MIDI 2.0 and the options release, likely concerning a function or method involved in managing or releasing MIDI 2.0-specific option data or resources." I immediately start mentally categorizing this. Is this low-level, high-level, embedded, host, a library function, or a hardware driver? Based on the naming convention (`f_`), I'm leaning towards a C function, or something functionally similar, in a lower level library. I need more context to be sure, of course.

The "release" part instantly flags potential memory management issues. Is it about freeing allocated memory, resetting option states, closing a connection, or maybe restoring default MIDI 2.0 settings? It's all very dependent on the context and the overall architecture, but my mind is already running through common memory management pitfalls and potential mutex or semaphore interactions that could be involved if this is a shared resource.

I also wonder about the potential data structures involved. Is this handling single option values, or batches of options? Are we looking at individual messages or a complete initialization sequence? Does it take a pointer to data, and release that, or does it release options from a higher-level object? What about error handling? Are we expecting a return value to indicate success or failure, or are exceptions being thrown? 

Now, the important part: what happens *before* this function is called? Is there an "allocate" or "initialize" counterpart? How is the option data set up in the first place? And after it's called, are there any further actions required, such as notifications or cleanup of other resources?

Essentially, I need to know the bigger picture. I'm already formulating questions about the function's signature, its dependencies, its intended purpose within the system, and its potential impact on the overall MIDI 2.0 implementation. This is going to be interesting.



33/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_opts_release]

Results:
map[SourceCode:2613:	static void f_midi2_opts_release(struct config_item *item)
2614:	{
2615:		struct f_midi2_opts *opts = to_f_midi2_opts(item);
2616:	
2617:		usb_put_function_instance(&opts->func_inst);
2618:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

34/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 16558
							output: 23
							thoughts: 131
						

Thoughts:
**Investigating Resource Deallocation in USB Function Instances**

Okay, so `usb_put_function_instance` is the key. I see it calls `fi->free_func_inst(fi)` when the reference count drops to zero. That's standard practice. Now, I need to trace this specifically for the MIDI2 function. Ah, here it is, `f_midi2_free_inst` gets called. This function *does* free `opts`. But... wait a minute, what about the default option groups? Specifically, `ep_opts` and `block_opts`? Are those getting handled correctly? I have a feeling there's a potential leak or improper cleanup lurking there.

When the parent config group (`opts->func_inst.group`) gets `config_item_put` on it, does ConfigFS automatically release those default groups? I don't think so, I need to go deeper. Let's dig into the ConfigFS code. I need to check `configfs_rmdir` and `config_item_put` in `fs/configfs/item.c`. That's where the magic happens and I'll find out what's really going on with the default groups.



35/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:config_item_release]

Results:
map[SourceCode: 135:	static void config_item_release(struct kref *kref)
 136:	{
 137:		config_item_cleanup(container_of(kref, struct config_item, ci_kref));
 138:	}
 SourceFile:fs/configfs/item.c]

36/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 17072
							output: 23
							thoughts: 8
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented as if it were my own internal monologue:

**Thinking Through Config Item Cleanup**

Alright, let's break this down. The core issue here seems to revolve around the handling and maintenance of configuration items. Specifically, I'm focusing on the `config_item_cleanup` component or function. My immediate thoughts go to several key areas:

*   **Necessity & Scope:** *Why* are we even cleaning up config items? Is this about stale data, redundant entries, security vulnerabilities related to outdated configurations, or perhaps optimization of resource usage? Knowing the *reason* dictates the approach. Is this a system-wide cleanup, focused on specific modules, or triggered by certain events? Defining the scope is critical to avoid impacting other components.

*   **Identification Strategy:** How do we *identify* items that need to be cleaned? Are we relying on timestamps, version numbers, usage metrics, or perhaps some form of external validation? The accuracy of this identification process is paramount, especially if there are dependencies or cascading effects on the rest of the system. I need to be certain about the criteria for deletion.

*   **Cleanup Mechanism:** What is the actual cleanup process? Is it a simple deletion, an archival, a re-validation, or a more complex series of steps? How will this cleanup interact with existing data models, permissions, and auditing systems? Any modification to the database needs to be carefully examined.

*   **Error Handling and Rollback:** What happens if the cleanup fails midway? Do we have robust error handling and, crucially, a rollback mechanism to prevent data corruption or inconsistencies? Resilience is paramount, as a failed cleanup could lead to critical system issues.

*   **Concurrency & Locking:** If this cleanup operation involves concurrent processing or database interactions, what measures are in place to ensure data integrity and avoid race conditions or deadlocks? The cleanup must operate correctly at any level of activity.

*   **Performance Considerations:** How will this cleanup process affect system performance, especially during peak load? Are we dealing with potential bottlenecks or performance impacts that need to be optimized? Should it be scheduled off-peak, and how aggressive should the policy be?

*   **Logging and Auditing:** Detailed logging and auditing are essential. We need to track *what* was cleaned, *when*, and *why*, along with any errors that occurred. This information is crucial for debugging, auditing, and meeting compliance requirements.

*   **Testing:** Thorough testing, including unit tests, integration tests, and potentially even performance tests, is a non-negotiable. We need to validate the identification logic, the cleanup process itself, the error handling, and the rollback mechanism. Edge cases and corner conditions need to be rigorously examined.

In short, "config\_item\_cleanup" is the starting point for a cascade of design considerations, each requiring careful attention to detail. Ignoring any of these aspects could result in instability, data loss, or system-wide disruption.



37/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:config_item_cleanup]

Results:
map[SourceCode: 117:	static void config_item_cleanup(struct config_item *item)
 118:	{
 119:		const struct config_item_type *t = item->ci_type;
 120:		struct config_group *s = item->ci_group;
 121:		struct config_item *parent = item->ci_parent;
 122:	
 123:		pr_debug("config_item %s: cleaning up\n", config_item_name(item));
 124:		if (item->ci_name != item->ci_namebuf)
 125:			kfree(item->ci_name);
 126:		item->ci_name = NULL;
 127:		if (t && t->ct_item_ops && t->ct_item_ops->release)
 128:			t->ct_item_ops->release(item);
 129:		if (s)
 130:			config_group_put(s);
 131:		if (parent)
 132:			config_item_put(parent);
 133:	}
 SourceFile:fs/configfs/item.c]

38/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 18053
							output: 22
							thoughts: 70
						

Thoughts:
**My Current Analysis of the Configfs Group Cleanup**

Okay, hold on a second... It's just hit me: `config_item_cleanup` *doesn't* actually free the default groups. That feels... wrong. I need to be sure. My recollection is that those default groups are linked to `group->default_groups`. Now, where and how are these default groups being created?

Ah, right! The creation happens when a directory is established. Specifically, `configfs_mkdir` does the deed, setting up those initial groups. Time to dive into the code. I need to refresh my memory on `configfs_mkdir` to pinpoint precisely what's happening. Let's head over to `fs/configfs/dir.c` and dig in.



39/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_mkdir]

Results:
map[SourceCode:1289:	static struct dentry *configfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
1290:					     struct dentry *dentry, umode_t mode)
1291:	{
1292:		int ret = 0;
1293:		int module_got = 0;
1294:		struct config_group *group = NULL;
1295:		struct config_item *item = NULL;
1296:		struct config_item *parent_item;
1297:		struct configfs_subsystem *subsys;
1298:		struct configfs_dirent *sd;
1299:		const struct config_item_type *type;
1300:		struct module *subsys_owner = NULL, *new_item_owner = NULL;
1301:		struct configfs_fragment *frag;
1302:		struct name_snapshot n;
1303:		const char *name;
1304:	
1305:		take_dentry_name_snapshot(&n, dentry);
1306:		name = n.name.name;
1307:	
1308:		sd = dentry->d_parent->d_fsdata;
1309:	
1310:		/*
1311:		 * Fake invisibility if dir belongs to a group/default groups hierarchy
1312:		 * being attached
1313:		 */
1314:		if (!configfs_dirent_is_ready(sd)) {
1315:			ret = -ENOENT;
1316:			goto out;
1317:		}
1318:	
1319:		if (!(sd->s_type & CONFIGFS_USET_DIR)) {
1320:			ret = -EPERM;
1321:			goto out;
1322:		}
1323:	
1324:		frag = new_fragment();
1325:		if (!frag) {
1326:			ret = -ENOMEM;
1327:			goto out;
1328:		}
1329:	
1330:		/* Get a working ref for the duration of this function */
1331:		parent_item = configfs_get_config_item(dentry->d_parent);
1332:		type = parent_item->ci_type;
1333:		subsys = to_config_group(parent_item)->cg_subsys;
1334:		BUG_ON(!subsys);
1335:	
1336:		if (!type || !type->ct_group_ops ||
1337:		    (!type->ct_group_ops->make_group &&
1338:		     !type->ct_group_ops->make_item)) {
1339:			ret = -EPERM;  /* Lack-of-mkdir returns -EPERM */
1340:			goto out_put;
1341:		}
1342:	
1343:		/*
1344:		 * The subsystem may belong to a different module than the item
1345:		 * being created.  We don't want to safely pin the new item but
1346:		 * fail to pin the subsystem it sits under.
1347:		 */
1348:		if (!subsys->su_group.cg_item.ci_type) {
1349:			ret = -EINVAL;
1350:			goto out_put;
1351:		}
1352:		subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
1353:		if (!try_module_get(subsys_owner)) {
1354:			ret = -EINVAL;
1355:			goto out_put;
1356:		}
1357:	
1358:		mutex_lock(&subsys->su_mutex);
1359:		if (type->ct_group_ops->make_group) {
1360:			group = type->ct_group_ops->make_group(to_config_group(parent_item), name);
1361:			if (!group)
1362:				group = ERR_PTR(-ENOMEM);
1363:			if (!IS_ERR(group)) {
1364:				link_group(to_config_group(parent_item), group);
1365:				item = &group->cg_item;
1366:			} else
1367:				ret = PTR_ERR(group);
1368:		} else {
1369:			item = type->ct_group_ops->make_item(to_config_group(parent_item), name);
1370:			if (!item)
1371:				item = ERR_PTR(-ENOMEM);
1372:			if (!IS_ERR(item))
1373:				link_obj(parent_item, item);
1374:			else
1375:				ret = PTR_ERR(item);
1376:		}
1377:		mutex_unlock(&subsys->su_mutex);
1378:	
1379:		if (ret) {
1380:			/*
1381:			 * If ret != 0, then link_obj() was never called.
1382:			 * There are no extra references to clean up.
1383:			 */
1384:			goto out_subsys_put;
1385:		}
1386:	
1387:		/*
1388:		 * link_obj() has been called (via link_group() for groups).
1389:		 * From here on out, errors must clean that up.
1390:		 */
1391:	
1392:		type = item->ci_type;
1393:		if (!type) {
1394:			ret = -EINVAL;
1395:			goto out_unlink;
1396:		}
1397:	
1398:		new_item_owner = type->ct_owner;
1399:		if (!try_module_get(new_item_owner)) {
1400:			ret = -EINVAL;
1401:			goto out_unlink;
1402:		}
1403:	
1404:		/*
1405:		 * I hate doing it this way, but if there is
1406:		 * an error,  module_put() probably should
1407:		 * happen after any cleanup.
1408:		 */
1409:		module_got = 1;
1410:	
1411:		/*
1412:		 * Make racing rmdir() fail if it did not tag parent with
1413:		 * CONFIGFS_USET_DROPPING
1414:		 * Note: if CONFIGFS_USET_DROPPING is already set, attach_group() will
1415:		 * fail and let rmdir() terminate correctly
1416:		 */
1417:		spin_lock(&configfs_dirent_lock);
1418:		/* This will make configfs_detach_prep() fail */
1419:		sd->s_type |= CONFIGFS_USET_IN_MKDIR;
1420:		spin_unlock(&configfs_dirent_lock);
1421:	
1422:		if (group)
1423:			ret = configfs_attach_group(item, dentry, frag);
1424:		else
1425:			ret = configfs_attach_item(item, dentry, frag);
1426:	
1427:		spin_lock(&configfs_dirent_lock);
1428:		sd->s_type &= ~CONFIGFS_USET_IN_MKDIR;
1429:		if (!ret)
1430:			configfs_dir_set_ready(dentry->d_fsdata);
1431:		spin_unlock(&configfs_dirent_lock);
1432:	
1433:	out_unlink:
1434:		if (ret) {
1435:			/* Tear down everything we built up */
1436:			mutex_lock(&subsys->su_mutex);
1437:	
1438:			client_disconnect_notify(parent_item, item);
1439:			if (group)
1440:				unlink_group(group);
1441:			else
1442:				unlink_obj(item);
1443:			client_drop_item(parent_item, item);
1444:	
1445:			mutex_unlock(&subsys->su_mutex);
1446:	
1447:			if (module_got)
1448:				module_put(new_item_owner);
1449:		}
1450:	
1451:	out_subsys_put:
1452:		if (ret)
1453:			module_put(subsys_owner);
1454:	
1455:	out_put:
1456:		/*
1457:		 * link_obj()/link_group() took a reference from child->parent,
1458:		 * so the parent is safely pinned.  We can drop our working
1459:		 * reference.
1460:		 */
1461:		config_item_put(parent_item);
1462:		put_fragment(frag);
1463:	
1464:	out:
1465:		release_dentry_name_snapshot(&n);
1466:		return ERR_PTR(ret);
1467:	}
 SourceFile:fs/configfs/dir.c]

40/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 20901
							output: 24
							thoughts: 17
						

Thoughts:
Here's my thought process, as if I were considering this myself:

**ConfigFS Group Attachment Point**

Okay, let me think this through... *Ah-ha!* Right, `configfs_attach_group`... that's where the default groups get hooked up. So, when the system or application or whatever it is is setting up, that's the key function to trace. It has to be - that's where the basic configuration comes in and associates groups. Let's see if I can find the default group attachment in here.



41/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_attach_group]

Results:
map[SourceCode: 891:	static int configfs_attach_group(struct config_item *item,
 892:					 struct dentry *dentry,
 893:					 struct configfs_fragment *frag)
 894:	{
 895:		int ret;
 896:		struct configfs_dirent *sd;
 897:	
 898:		ret = configfs_attach_item(item, dentry, frag);
 899:		if (!ret) {
 900:			sd = dentry->d_fsdata;
 901:			sd->s_type |= CONFIGFS_USET_DIR;
 902:	
 903:			/*
 904:			 * FYI, we're faking mkdir in populate_groups()
 905:			 * We must lock the group's inode to avoid races with the VFS
 906:			 * which can already hit the inode and try to add/remove entries
 907:			 * under it.
 908:			 *
 909:			 * We must also lock the inode to remove it safely in case of
 910:			 * error, as rmdir() would.
 911:			 */
 912:			inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD);
 913:			configfs_adjust_dir_dirent_depth_before_populate(sd);
 914:			ret = populate_groups(to_config_group(item), frag);
 915:			if (ret) {
 916:				configfs_detach_group(dentry);
 917:				d_inode(dentry)->i_flags |= S_DEAD;
 918:				dont_mount(dentry);
 919:			}
 920:			configfs_adjust_dir_dirent_depth_after_populate(sd);
 921:			inode_unlock(d_inode(dentry));
 922:			if (ret)
 923:				d_delete(dentry);
 924:		}
 925:	
 926:		return ret;
 927:	}
 SourceFile:fs/configfs/dir.c]

42/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 21651
							output: 21
							thoughts: 6
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:

**My Reasoning for `populate_groups`**

Alright, I'm thinking about this `populate_groups` function, and how it fits into the larger architecture. My initial instinct is to consider its purpose. From what I see I must be populating groups in a database or a data structure somehow. It's likely a critical piece in initializing some kind of organizational framework. I need to drill down into the details. What exactly constitutes a "group" in this context? Is it based on attributes, relationships, user roles, some combination of these? Understanding the defining characteristics of a group will be key.

I must also think about the source of the data to populate these groups. Is it pulling from a single data source or multiple sources? Are the sources structured or unstructured? Are there any data cleaning or transformation steps involved before the population process? And how does this function handle edge cases or error conditions? Data integrity is paramount, so I have to think about validation and error handling to ensure I'm not creating corrupt or inconsistent groups.

Moreover, I'm already anticipating the performance implications. The sheer volume of data involved could be significant, so I must assess the complexity of the population algorithm. Is this a naive approach, or is there an opportunity for optimization? Can I leverage indexing, caching, or parallel processing to speed things up? I'm wondering what the time and space complexity of the process is.

Finally, how does `populate_groups` integrate with other components of the system? Are there any dependencies? How does it interact with other modules that might be responsible for group management, access control, or reporting? I must consider the entire workflow to make sure that this function fits seamlessly within the larger system.



43/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:populate_groups]

Results:
map[SourceCode: 734:	static int populate_groups(struct config_group *group,
 735:				   struct configfs_fragment *frag)
 736:	{
 737:		struct dentry *parent = group->cg_item.ci_dentry;
 738:		struct config_group *new_group;
 739:	
 740:		list_for_each_entry(new_group, &group->default_groups, group_entry) {
 741:			int ret = create_default_group(parent, new_group, frag);
 742:			if (ret)
 743:				return ret;
 744:		}
 745:		return 0;
 746:	}
 SourceFile:fs/configfs/dir.c]

44/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 22283
							output: 23
							thoughts: 8
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented in the first person:

**My Reasoning on Default Group Creation**

Right, so I'm thinking about the function to create a default group.  This is a core component, something that sets up the initial environment. I need to make sure this is robust and handles all the edge cases properly. First, I have to consider the initial state of the system and make sure all default settings are applied correctly, I have to ensure the group has a unique ID and a meaningful, recognizable name. I'm also considering the permissions associated with this default group, and those permissions need to align with best practices for security and usability.

Let's see, what else? I should ensure it's integrated seamlessly into the existing workflow. Any dependencies on external services or configuration files need to be handled gracefully – error handling is critical here. If something goes wrong during creation, I need informative logging and perhaps a fallback mechanism or an exception that can be caught and handled gracefully upstream.

Furthermore, I have to think about how this interacts with the rest of the system. Does the creation trigger any downstream events or notifications? Does it update any caches or indexes? I'll need to consider those implications. And, of course, documentation.  I need to make this function well-documented so that anyone coming along later (including myself in six months!) can easily understand its purpose and behavior. Ultimately, I'm aiming for a default group that is both useful out-of-the-box and easily configurable to meet specific needs.



45/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:create_default_group]

Results:
map[SourceCode: 695:	/*
 696:	 * This fakes mkdir(2) on a default_groups[] entry.  It
 697:	 * creates a dentry, attachs it, and then does fixup
 698:	 * on the sd->s_type.
 699:	 *
 700:	 * We could, perhaps, tweak our parent's ->mkdir for a minute and
 701:	 * try using vfs_mkdir.  Just a thought.
 702:	 */
 703:	static int create_default_group(struct dentry *parent,
 704:					struct config_group *group,
 705:					struct configfs_fragment *frag)
 706:	{
 707:		int ret;
 708:		struct configfs_dirent *sd;
 709:		/* We trust the caller holds a reference to parent */
 710:		struct dentry *child;
 711:	
 712:		if (!group->cg_item.ci_name)
 713:			group->cg_item.ci_name = group->cg_item.ci_namebuf;
 714:	
 715:		ret = -ENOMEM;
 716:		child = d_alloc_name(parent, group->cg_item.ci_name);
 717:		if (child) {
 718:			d_add(child, NULL);
 719:	
 720:			ret = configfs_attach_group(&group->cg_item, child, frag);
 721:			if (!ret) {
 722:				sd = child->d_fsdata;
 723:				sd->s_type |= CONFIGFS_USET_DEFAULT;
 724:			} else {
 725:				BUG_ON(d_inode(child));
 726:				d_drop(child);
 727:			}
 728:			dput(child);
 729:		}
 730:	
 731:		return ret;
 732:	}
 SourceFile:fs/configfs/dir.c]

46/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 23226
							output: 23
							thoughts: 35
						

Thoughts:
Okay, here's my interpretation of those thoughts, tailored for an expert audience, presented in the first person:

**Navigating the Configuration Filesystem Group Removal**

Alright, let me unpack this in my head. `create_default_group` essentially lays the groundwork, right? It's the function that crafts the `dentry` structure for the default group, linking it seamlessly to the relevant group configuration. Standard stuff. The key trigger here, in the removal process, is `configfs_rmdir`. This is where it gets interesting, as this likely implies the deletion of the parent group. What happens when it is triggered from a parent directory? This implies recursive operations on the subtree. We are therefore responsible for making sure we can handle this gracefully.



47/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_rmdir]

Results:
map[SourceCode:1469:	static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1470:	{
1471:		struct config_item *parent_item;
1472:		struct config_item *item;
1473:		struct configfs_subsystem *subsys;
1474:		struct configfs_dirent *sd;
1475:		struct configfs_fragment *frag;
1476:		struct module *subsys_owner = NULL, *dead_item_owner = NULL;
1477:		int ret;
1478:	
1479:		sd = dentry->d_fsdata;
1480:		if (sd->s_type & CONFIGFS_USET_DEFAULT)
1481:			return -EPERM;
1482:	
1483:		/* Get a working ref until we have the child */
1484:		parent_item = configfs_get_config_item(dentry->d_parent);
1485:		subsys = to_config_group(parent_item)->cg_subsys;
1486:		BUG_ON(!subsys);
1487:	
1488:		if (!parent_item->ci_type) {
1489:			config_item_put(parent_item);
1490:			return -EINVAL;
1491:		}
1492:	
1493:		/* configfs_mkdir() shouldn't have allowed this */
1494:		BUG_ON(!subsys->su_group.cg_item.ci_type);
1495:		subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
1496:	
1497:		/*
1498:		 * Ensure that no racing symlink() will make detach_prep() fail while
1499:		 * the new link is temporarily attached
1500:		 */
1501:		do {
1502:			struct dentry *wait;
1503:	
1504:			mutex_lock(&configfs_symlink_mutex);
1505:			spin_lock(&configfs_dirent_lock);
1506:			/*
1507:			 * Here's where we check for dependents.  We're protected by
1508:			 * configfs_dirent_lock.
1509:			 * If no dependent, atomically tag the item as dropping.
1510:			 */
1511:			ret = sd->s_dependent_count ? -EBUSY : 0;
1512:			if (!ret) {
1513:				ret = configfs_detach_prep(sd, &wait);
1514:				if (ret)
1515:					configfs_detach_rollback(sd);
1516:			}
1517:			spin_unlock(&configfs_dirent_lock);
1518:			mutex_unlock(&configfs_symlink_mutex);
1519:	
1520:			if (ret) {
1521:				if (ret != -EAGAIN) {
1522:					config_item_put(parent_item);
1523:					return ret;
1524:				}
1525:	
1526:				/* Wait until the racing operation terminates */
1527:				inode_lock(d_inode(wait));
1528:				inode_unlock(d_inode(wait));
1529:				dput(wait);
1530:			}
1531:		} while (ret == -EAGAIN);
1532:	
1533:		frag = sd->s_frag;
1534:		if (down_write_killable(&frag->frag_sem)) {
1535:			spin_lock(&configfs_dirent_lock);
1536:			configfs_detach_rollback(sd);
1537:			spin_unlock(&configfs_dirent_lock);
1538:			config_item_put(parent_item);
1539:			return -EINTR;
1540:		}
1541:		frag->frag_dead = true;
1542:		up_write(&frag->frag_sem);
1543:	
1544:		/* Get a working ref for the duration of this function */
1545:		item = configfs_get_config_item(dentry);
1546:	
1547:		/* Drop reference from above, item already holds one. */
1548:		config_item_put(parent_item);
1549:	
1550:		if (item->ci_type)
1551:			dead_item_owner = item->ci_type->ct_owner;
1552:	
1553:		if (sd->s_type & CONFIGFS_USET_DIR) {
1554:			configfs_detach_group(dentry);
1555:	
1556:			mutex_lock(&subsys->su_mutex);
1557:			client_disconnect_notify(parent_item, item);
1558:			unlink_group(to_config_group(item));
1559:		} else {
1560:			configfs_detach_item(dentry);
1561:	
1562:			mutex_lock(&subsys->su_mutex);
1563:			client_disconnect_notify(parent_item, item);
1564:			unlink_obj(item);
1565:		}
1566:	
1567:		client_drop_item(parent_item, item);
1568:		mutex_unlock(&subsys->su_mutex);
1569:	
1570:		/* Drop our reference from above */
1571:		config_item_put(item);
1572:	
1573:		module_put(dead_item_owner);
1574:		module_put(subsys_owner);
1575:	
1576:		return 0;
1577:	}
 SourceFile:fs/configfs/dir.c]

48/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 25067
							output: 24
							thoughts: 22
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Analyzing `configfs_detach_group`**

Okay, so `configfs_detach_group` is the function responsible for detaching a group. That's the key operation I need to understand. Let's dig into it. I need to see exactly what's going on under the hood when a group is detached within the ConfigFS framework. What are the resources being released? What locks are being acquired and released? I suspect it's going to be doing cleanup on all the targets within that particular group, unlinking from the filesystem, and likely some reference counting adjustments. I should see how it handles potential errors during the unlinking process and how it ensures consistency. I also need to be mindful of any interaction with potential concurrent operations on the group or its children. Time to dive into the code!



49/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_detach_group]

Results:
map[SourceCode: 884:	/* Caller holds the mutex of the group's inode */
 885:	static void configfs_detach_group(struct dentry *dentry)
 886:	{
 887:		detach_groups(dentry);
 888:		configfs_detach_item(dentry);
 889:	}
 SourceFile:fs/configfs/dir.c]

50/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 25420
							output: 21
							thoughts: 6
						

Thoughts:
Okay, here's my interpretation of that thought process, summarized as you requested:

**Deconstructing and Understanding Group Dynamics**

Alright, let's break this down. When I see `detach_groups`, my mind immediately goes to the practical implications. I'm thinking about situations where we need to isolate or remove certain groups from a larger context. This could be for a variety of reasons, right? Maybe it's data privacy, perhaps it's resource allocation, or potentially for a more refined analysis where the presence of certain groups introduces unwanted noise or bias.

I'm considering the potential impact on downstream processes. What happens to the detached groups? Are they archived, deleted, or transferred elsewhere? The mechanics of *how* the detachment happens are paramount, are we talking about a hard split, a soft copy, or a more complex re-attribution? The specific implementation will hinge heavily on the specific dataset and its use case. I need to be thinking about data integrity and how we ensure consistency after the split. Any potential dependencies between the detached and remaining groups are important. We can't have a cascading failure.

I also need to evaluate the implications on any underlying models or algorithms that are working with this dataset, and the specific architecture of the system. I also think about how to define these "groups". The underlying grouping mechanism and the process for defining those groups is a critical factor and must be defined very carefully. I'm mentally checking what edge cases I should consider, along with how to maintain metadata and context during the detaching process. Basically, I'm already formulating a checklist for best practices to guarantee the change is well-managed.



51/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:detach_groups]

Results:
map[SourceCode: 664:	static void detach_groups(struct dentry *dentry)
 665:	{
 666:		struct dentry *child;
 667:		struct configfs_dirent *parent_sd;
 668:		struct configfs_dirent *sd, *next;
 669:	
 670:		parent_sd = dentry->d_fsdata;
 671:		spin_lock(&configfs_dirent_lock);
 672:		for (sd = next_dirent(parent_sd, NULL); sd; sd = next) {
 673:			next = next_dirent(parent_sd, sd);
 674:			if (!(sd->s_type & CONFIGFS_USET_DEFAULT))
 675:				continue;
 676:	
 677:			child = dget(sd->s_dentry);
 678:			spin_unlock(&configfs_dirent_lock);
 679:	
 680:			inode_lock(d_inode(child));
 681:	
 682:			configfs_detach_group(child);
 683:			d_inode(child)->i_flags |= S_DEAD;
 684:			dont_mount(child);
 685:	
 686:			inode_unlock(d_inode(child));
 687:	
 688:			d_delete(child);
 689:			dput(child);
 690:			spin_lock(&configfs_dirent_lock);
 691:		}
 692:		spin_unlock(&configfs_dirent_lock);
 693:	}
 SourceFile:fs/configfs/dir.c]

52/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 26259
							output: 24
							thoughts: 44
						

Thoughts:
Okay, here's my interpretation of this thought process, keeping in mind my expertise:

**Diving into the ConfigFS Detachment Logic**

Alright, let's break this down. My mind immediately jumped into the details when I saw `detach_groups`. I know that means `configfs_detach_group(child)` is probably invoked in there somewhere, and that's going to lead us to the actual detachment functionality, the nuts and bolts. And yes, confirmed! `configfs_detach_group(child)` is indeed called, which then triggers `configfs_detach_item(child)`. That's the real core function I need to understand here. My experience tells me that's where the resource cleanup and structure unlinking are going to be handled. I need to refresh my memory on what that `child` is and how it ties into the overall ConfigFS tree structure, and then zoom in on `configfs_detach_item`'s internal workings. Let's see what that function does!



53/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_detach_item]

Results:
map[SourceCode: 835:	/* Caller holds the mutex of the item's inode */
 836:	static void configfs_detach_item(struct dentry *dentry)
 837:	{
 838:		detach_attrs(dentry);
 839:		configfs_remove_dir(dentry);
 840:	}
 SourceFile:fs/configfs/dir.c]

54/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 26662
							output: 24
							thoughts: 130
						

Thoughts:
Here's my thought process, as an expert in this area:

**Digging into ConfigFS Reference Counting**

Okay, so I'm looking at `configfs_detach_item` and something feels off. It doesn't seem to call `config_item_put` on the default groups, which strikes me as a potential memory leak or at least a reference counting inconsistency. That's a red flag. Let me see...

Now, I'm questioning how references are handled when we call `create_default_group`. Does it increment the refcount on the default group? I need to clarify that. Let's trace through that function again to be sure...

Okay, re-examining `create_default_group`... I see this line: `ret = configfs_attach_group(&group->cg_item, child, frag);`. So `create_default_group` calls `configfs_attach_group`. `configfs_attach_group` is interesting because it calls `configfs_attach_item`, which in turn calls `configfs_make_dirent`. My attention is now focused on the items.

Let's quickly check this. Does `configfs_attach_item` increment the reference count of the item? I need to be sure the item is properly accounted for in the system. I have to verify where these references are coming from. The goal is to make sure this item is accounted for and not leaked.



55/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_attach_item]

Results:
map[SourceCode: 842:	/*
 843:	 * The goal is that configfs_attach_item() (and
 844:	 * configfs_attach_group()) can be called from either the VFS or this
 845:	 * module.  That is, they assume that the items have been created,
 846:	 * the dentry allocated, and the dcache is all ready to go.
 847:	 *
 848:	 * If they fail, they must clean up after themselves as if they
 849:	 * had never been called.  The caller (VFS or local function) will
 850:	 * handle cleaning up the dcache bits.
 851:	 *
 852:	 * configfs_detach_group() and configfs_detach_item() behave similarly on
 853:	 * the way out.  They assume that the proper semaphores are held, they
 854:	 * clean up the configfs items, and they expect their callers will
 855:	 * handle the dcache bits.
 856:	 */
 857:	static int configfs_attach_item(struct config_item *item,
 858:					struct dentry *dentry,
 859:					struct configfs_fragment *frag)
 860:	{
 861:		int ret;
 862:	
 863:		ret = configfs_create_dir(item, dentry, frag);
 864:		if (!ret) {
 865:			ret = populate_attrs(item);
 866:			if (ret) {
 867:				/*
 868:				 * We are going to remove an inode and its dentry but
 869:				 * the VFS may already have hit and used them. Thus,
 870:				 * we must lock them as rmdir() would.
 871:				 */
 872:				inode_lock(d_inode(dentry));
 873:				configfs_detach_item(dentry);
 874:				d_inode(dentry)->i_flags |= S_DEAD;
 875:				dont_mount(dentry);
 876:				inode_unlock(d_inode(dentry));
 877:				d_delete(dentry);
 878:			}
 879:		}
 880:	
 881:		return ret;
 882:	}
 SourceFile:fs/configfs/dir.c]

56/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 27787
							output: 24
							thoughts: 12
						

Thoughts:
Okay, let's dive into this. Here's my take on `configfs_create_dir`, as if these are my immediate thoughts:

**Dissecting `configfs_create_dir`**

Alright, so we're looking at `configfs_create_dir`. Immediately, I'm thinking, this must be a core function for manipulating the configfs structure, probably responsible for... creating a directory, obviously! But the details are key here. I need to figure out the implications of that directory's existence within the configfs hierarchy. What exactly is being represented? Is it a device, an attribute grouping, a logical container of some kind?

The name suggests a directory, but configfs is all about virtual filesystems. So this directory isn't *really* a traditional filesystem directory, right? It's likely a virtual node that maps to an underlying data structure somewhere. The function will need to manage the metadata, the permissions, the links, everything required to make this new virtual directory function correctly within the configfs framework.

I'll be looking for things like:

*   **Error handling:** What happens if the directory already exists? Or if the system is low on resources? What error codes are being returned and how are they being handled upstream? I expect robust error handling is crucial for configfs, as it's often a crucial user-space interface.
*   **Security Context:** This likely involves setting the appropriate ownership and permissions for the new directory. This is critical for controlling access to whatever this directory represents. I'll need to understand how the security context is being established (root, particular user? What capabilities are required?)
*   **Data Structure Association:** What underlying data structure in the kernel is linked to this directory? Is it a generic container or something specific to the device/interface/whatever configfs is modeling? How is that association maintained? And how are the relevant data structures being locked or managed to ensure atomicity and thread safety?
*   **Lifecycle Management:** Is there a corresponding `configfs_remove_dir` or something similar? How does that work? What happens to the underlying data when the directory is removed? Are there any cleanup tasks required to free resources?

Ultimately, the goal is to fully understand how this `configfs_create_dir` function fits into the bigger picture of configfs, and how it is employed to build and structure the virtual filesystem.



57/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_create_dir]

Results:
map[SourceCode: 293:	static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
 294:					struct configfs_fragment *frag)
 295:	{
 296:		int error;
 297:		umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
 298:		struct dentry *p = dentry->d_parent;
 299:		struct inode *p_inode = d_inode(p);
 300:		struct inode *inode;
 301:	
 302:		BUG_ON(!item);
 303:	
 304:		error = configfs_make_dirent(p->d_fsdata, dentry, item, mode,
 305:					     CONFIGFS_DIR | CONFIGFS_USET_CREATING,
 306:					     frag);
 307:		if (unlikely(error))
 308:			return error;
 309:	
 310:		configfs_set_dir_dirent_depth(p->d_fsdata, dentry->d_fsdata);
 311:		inode = configfs_create(dentry, mode);
 312:		if (IS_ERR(inode))
 313:			goto out_remove;
 314:	
 315:		inode->i_op = &configfs_dir_inode_operations;
 316:		inode->i_fop = &configfs_dir_operations;
 317:		/* directory inodes start off with i_nlink == 2 (for "." entry) */
 318:		inc_nlink(inode);
 319:		d_make_persistent(dentry, inode);
 320:		inc_nlink(p_inode);
 321:		inode_set_mtime_to_ts(p_inode, inode_set_ctime_current(p_inode));
 322:		item->ci_dentry = dentry;
 323:		return 0;
 324:	
 325:	out_remove:
 326:		configfs_put(dentry->d_fsdata);
 327:		configfs_remove_dirent(dentry);
 328:		return PTR_ERR(inode);
 329:	}
 SourceFile:fs/configfs/dir.c]

58/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 28979
							output: 25
							thoughts: 35
						

Thoughts:
Okay, here's my interpretation of that thought process, from an expert's perspective:

**Diving into the `configfs_make_dirent` Implementation**

Wait a second...I'm reviewing this `configfs` code, and something's bugging me. Specifically, I'm looking at `configfs_make_dirent` and it *doesn't* appear to take a reference on the `item` structure it's using? That seems unusual, even potentially problematic in a concurrent environment like this. I'd expect some form of reference counting or locking to ensure the `item` data remains valid while the directory entry is active. This smells like a subtle, but potentially nasty, race condition. I need to understand this better. Let's get right into the code for `configfs_make_dirent` and see what's actually happening under the hood. I need to confirm whether my concern is valid or if the surrounding code handles this implicitly somehow. Time to dig in and clarify this!



59/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_make_dirent]

Results:
map[SourceCode: 253:	int configfs_make_dirent(struct configfs_dirent * parent_sd,
 254:				 struct dentry * dentry, void * element,
 255:				 umode_t mode, int type, struct configfs_fragment *frag)
 256:	{
 257:		struct configfs_dirent * sd;
 258:	
 259:		sd = configfs_new_dirent(parent_sd, element, type, frag);
 260:		if (IS_ERR(sd))
 261:			return PTR_ERR(sd);
 262:	
 263:		sd->s_mode = mode;
 264:		sd->s_dentry = dentry;
 265:		if (dentry)
 266:			dentry->d_fsdata = configfs_get(sd);
 267:	
 268:		return 0;
 269:	}
 SourceFile:fs/configfs/dir.c]

60/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 29542
							output: 23
							thoughts: 481
						

Thoughts:
**Digging into ConfigFS Reference Counting**

Okay, so I'm focusing on how `configfs` handles references, specifically with default groups.  My initial thought was about how `configfs_new_dirent` just sets `sd->s_element = element`.  That *suggests* it doesn't take an explicit reference on the default group items themselves. And that's correct, they're part of the parent group.

Now I'm looking at `f_midi2_alloc_inst`.  Specifically this code block:

```c
	config_group_init_type_name(&opts->func_inst.group, "",
				    &f_midi2_func_type);

	config_group_init_type_name(&ep_opts->group, "ep.0",
				    &f_midi2_ep_type);
	configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);

	config_group_init_type_name(&block_opts->group, "block.0",
				    &f_midi2_block_type);
	configfs_add_default_group(&block_opts->group, &ep_opts->group);
```

I'm following the lifetime here. When `opts->func_inst.group` is released, `f_midi2_opts_release` gets called which then calls `usb_put_function_instance(&opts->func_inst)`. That in turn calls `f_midi2_free_inst`, and that frees `opts`. Seems straightforward.  But, what about `ep_opts` and `block_opts`? They're allocated using `kzalloc_obj` in `f_midi2_ep_opts_create` and `f_midi2_block_opts_create`.  I see that they get freed in `f_midi2_ep_opts_release` and `f_midi2_block_opts_release`.

The crucial question is, *who* triggers those `*_opts_release` functions? It looks like `f_midi2_ep_opts_release` is called when the `ep_opts->group.cg_item` refcount hits zero. But who is *decrementing* that refcount?  I need to trace the calls to `config_item_put` for the default groups to understand this.  Essentially, does `configfs` automatically drop the reference of a default group when its parent group is released?

I'm going to revisit `config_item_cleanup` and carefully trace how the refcounts are being managed.  That's where the answer is going to lie.



61/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:config_item_cleanup]

Results:
map[SourceCode: 117:	static void config_item_cleanup(struct config_item *item)
 118:	{
 119:		const struct config_item_type *t = item->ci_type;
 120:		struct config_group *s = item->ci_group;
 121:		struct config_item *parent = item->ci_parent;
 122:	
 123:		pr_debug("config_item %s: cleaning up\n", config_item_name(item));
 124:		if (item->ci_name != item->ci_namebuf)
 125:			kfree(item->ci_name);
 126:		item->ci_name = NULL;
 127:		if (t && t->ct_item_ops && t->ct_item_ops->release)
 128:			t->ct_item_ops->release(item);
 129:		if (s)
 130:			config_group_put(s);
 131:		if (parent)
 132:			config_item_put(parent);
 133:	}
 SourceFile:fs/configfs/item.c]

62/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 30958
							output: 24
							thoughts: 236
						

Thoughts:
**Analyzing the `config_item_cleanup` Process**

Okay, so I was thinking that `config_item_cleanup` might be responsible for iterating through and decrementing the reference counts of the `default_groups`, but that's not quite right. Wait a minute... if `ep_opts` is a default group belonging to `opts->func_inst.group`, then when `opts->func_inst.group` is initially created, `config_group_init_type_name` sets its refcount to 1, right? And checking further back, `config_group_init_type_name` in turn calls `config_item_init_type_name`, which is also what sets the refcount to 1. So, `ep_opts->group.cg_item` does indeed start with a refcount of 1.

Now, remembering what happens when a directory is made for `opts->func_inst.group` using `configfs_mkdir`, `populate_groups` comes into play and creates dentries for these default groups. Then, when the directory is removed using `configfs_rmdir`, this calls `configfs_detach_group`, which then calls `detach_groups`, which removes the dentries of default groups.

But, and here's the crucial question, does it actually *drop* the reference count of the default group items during that directory removal process? I need to check `configfs_detach_group` more closely to be sure.



63/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_detach_group]

Results:
map[SourceCode: 884:	/* Caller holds the mutex of the group's inode */
 885:	static void configfs_detach_group(struct dentry *dentry)
 886:	{
 887:		detach_groups(dentry);
 888:		configfs_detach_item(dentry);
 889:	}
 SourceFile:fs/configfs/dir.c]

64/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 31656
							output: 21
							thoughts: 6
						

Thoughts:
Okay, here's my interpretation of that thought process, summarized as you requested:

**Deconstructing and Understanding Group Dynamics**

Alright, let's break this down. When I see `detach_groups`, my mind immediately goes to the practical implications. I'm thinking about situations where we need to isolate or remove certain groups from a larger context. This could be for a variety of reasons, right? Maybe it's data privacy, perhaps it's resource allocation, or potentially for a more refined analysis where the presence of certain groups introduces unwanted noise or bias.

I'm considering the potential impact on downstream processes. What happens to the detached groups? Are they archived, deleted, or transferred elsewhere? The mechanics of *how* the detachment happens are paramount, are we talking about a hard split, a soft copy, or a more complex re-attribution? The specific implementation will hinge heavily on the specific dataset and its use case. I need to be thinking about data integrity and how we ensure consistency after the split. Any potential dependencies between the detached and remaining groups are important. We can't have a cascading failure.

I also need to evaluate the implications on any underlying models or algorithms that are working with this dataset, and the specific architecture of the system. I also think about how to define these "groups". The underlying grouping mechanism and the process for defining those groups is a critical factor and must be defined very carefully. I'm mentally checking what edge cases I should consider, along with how to maintain metadata and context during the detaching process. Basically, I'm already formulating a checklist for best practices to guarantee the change is well-managed.



65/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:detach_groups]

Results:
map[SourceCode: 664:	static void detach_groups(struct dentry *dentry)
 665:	{
 666:		struct dentry *child;
 667:		struct configfs_dirent *parent_sd;
 668:		struct configfs_dirent *sd, *next;
 669:	
 670:		parent_sd = dentry->d_fsdata;
 671:		spin_lock(&configfs_dirent_lock);
 672:		for (sd = next_dirent(parent_sd, NULL); sd; sd = next) {
 673:			next = next_dirent(parent_sd, sd);
 674:			if (!(sd->s_type & CONFIGFS_USET_DEFAULT))
 675:				continue;
 676:	
 677:			child = dget(sd->s_dentry);
 678:			spin_unlock(&configfs_dirent_lock);
 679:	
 680:			inode_lock(d_inode(child));
 681:	
 682:			configfs_detach_group(child);
 683:			d_inode(child)->i_flags |= S_DEAD;
 684:			dont_mount(child);
 685:	
 686:			inode_unlock(d_inode(child));
 687:	
 688:			d_delete(child);
 689:			dput(child);
 690:			spin_lock(&configfs_dirent_lock);
 691:		}
 692:		spin_unlock(&configfs_dirent_lock);
 693:	}
 SourceFile:fs/configfs/dir.c]

66/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 32495
							output: 24
							thoughts: 44
						

Thoughts:
Okay, let's see. My mind's buzzing... I'm tracing through this code, and I see that `configfs_detach_group` ultimately calls `configfs_detach_item`, which then calls `configfs_remove_dir`. Hmm, now the question is: does `configfs_remove_dir` handle the necessary refcount dropping on the directory? If it doesn't, we have a memory leak situation. I need to dig deeper into the implementation of `configfs_remove_dir` to be absolutely certain it's doing its job correctly. It's a critical point for resource management in this context. I'll have to investigate that function's implementation next.



67/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_remove_dir]

Results:
map[SourceCode: 410:	static void configfs_remove_dir(struct dentry *d)
 411:	{
 412:		struct dentry * parent = dget(d->d_parent);
 413:	
 414:		configfs_remove_dirent(d);
 415:	
 416:		if (d_really_is_positive(d)) {
 417:			if (unlikely(simple_rmdir(d_inode(parent), d)))
 418:				pr_warn("remove_dir (%pd): attributes remain", d);
 419:		}
 420:	
 421:		pr_debug(" o %pd removing done (%d)\n", d, d_count(d));
 422:	
 423:		dput(parent);
 424:	}
 SourceFile:fs/configfs/dir.c]

68/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 32964
							output: 24
							thoughts: 62
						

Thoughts:
**Investigating ConfigFS Refcount Behavior**

Okay, so I'm hitting a roadblock. It's becoming clear that something isn't quite right with how ConfigFS is handling refcounts, specifically with default groups. My initial thought was that it should handle it, but I'm no longer sure. Who *is* responsible for decrementing the refcount on these default groups if ConfigFS isn't?

I need to dig deeper. To understand the pattern for this, I'm thinking I should look at how this is handled elsewhere. Let's see how other USB functions manage default groups, perhaps within the existing gadget framework. I'll take a look at `f_mass_storage.c` or `f_uvc.c` as potential starting points to see if they offer any clues. Perhaps there's a common pattern to how this is handled, and I've missed it.



69/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:fsg_alloc_inst]

Results:
map[SourceCode:3494:	static struct usb_function_instance *fsg_alloc_inst(void)
3495:	{
3496:		struct fsg_opts *opts;
3497:		struct fsg_lun_config config;
3498:		int rc;
3499:	
3500:		opts = kzalloc_obj(*opts);
3501:		if (!opts)
3502:			return ERR_PTR(-ENOMEM);
3503:		mutex_init(&opts->lock);
3504:		opts->func_inst.free_func_inst = fsg_free_inst;
3505:		opts->common = fsg_common_setup(opts->common);
3506:		if (IS_ERR(opts->common)) {
3507:			rc = PTR_ERR(opts->common);
3508:			goto release_opts;
3509:		}
3510:	
3511:		rc = fsg_common_set_num_buffers(opts->common,
3512:						CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
3513:		if (rc)
3514:			goto release_common;
3515:	
3516:		pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
3517:	
3518:		memset(&config, 0, sizeof(config));
3519:		config.removable = true;
3520:		rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0",
3521:				(const char **)&opts->func_inst.group.cg_item.ci_name);
3522:		if (rc)
3523:			goto release_buffers;
3524:	
3525:		opts->lun0.lun = opts->common->luns[0];
3526:		opts->lun0.lun_id = 0;
3527:	
3528:		config_group_init_type_name(&opts->func_inst.group, "", &fsg_func_type);
3529:	
3530:		config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
3531:		configfs_add_default_group(&opts->lun0.group, &opts->func_inst.group);
3532:	
3533:		return &opts->func_inst;
3534:	
3535:	release_buffers:
3536:		fsg_common_free_buffers(opts->common);
3537:	release_common:
3538:		kfree(opts->common);
3539:	release_opts:
3540:		kfree(opts);
3541:		return ERR_PTR(rc);
3542:	}
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

70/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 34052
							output: 24
							thoughts: 9
						

Thoughts:
Okay, here's my attempt at summarizing the thought process, tailored for an expert audience, and written in the first person:

**My Deep Dive into `fsg_free_inst`**

Alright, let's break this down. When I see `fsg_free_inst`, my mind immediately jumps to memory management within, most likely, a complex system like a file system or a similar data structure. The "fsg" prefix strongly suggests a connection to a file system, while "free_inst" screams that we're dealing with freeing up instances – blocks, inodes, descriptors, whatever is relevant in this context. The context is really important to understand here, the function call alone doesn't tell us everything. It’s a pointer to some sort of memory deallocation function.

I immediately consider the implications. I know that if these resources aren't properly freed, we are risking memory leaks, which are death to any system. Even worse, if there's a double-free scenario, it could result in data corruption, and system crashes, as well.

I’m immediately wondering about the surrounding code. Is this function called deterministically, or is it triggered by some event, like error recovery or graceful shutdown? What is the function’s overall lifecycle and are there any checks to ensure we are actually cleaning up the memory that needs freeing? How does it interact with other memory management functions or locking mechanisms?

My immediate checklist would include:

*   **Error Handling:** Are there checks for null pointers or invalid states before the free operation? Are exceptions being properly thrown to the calling function, or are we just letting the problem bubble up?
*   **Synchronization:** How is concurrent access handled? Is there a mutex or some other locking mechanism to prevent race conditions during deallocation, especially in a multithreaded environment? Is there any reentrancy, where we might need to handle this?
*   **Resource Tracking:** Is there some sort of accounting – a reference count, perhaps – to ensure that the instance is not freed prematurely while it’s still in use? This is vital in systems that deal with shared resources.
*   **Integration:** How does this function interface with the rest of the file system's memory management or other system's memory management? What happens to the freed memory; is it returned to a general pool, or used in a special allocation routine?

My goal would be to gain a complete understanding of this function's role in the larger system. I’d want to map out its dependencies and implications, because improper use of `fsg_free_inst` is a ticking time bomb.



71/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:fsg_free_inst]

Results:
map[SourceCode:3485:	static void fsg_free_inst(struct usb_function_instance *fi)
3486:	{
3487:		struct fsg_opts *opts;
3488:	
3489:		opts = fsg_opts_from_func_inst(fi);
3490:		fsg_common_release(opts->common);
3491:		kfree(opts);
3492:	}
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

72/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 34790
							output: 28
							thoughts: 161
						

Thoughts:
**Analyzing the Data Structures in USB Gadget Driver Code**

Okay, let's break this down. First, I see that `fsg_opts` has `opts->lun0.group` embedded within it. This is important to note because it means that when the `opts` structure is freed, the memory for `lun0` (and consequently its group) is also released. This is standard practice, but it's crucial to confirm this implicit relationship to be certain of correct memory management.

However, the contrast that jumps out is in `f_midi2` where I recall `ep_opts` and `block_opts` are created using `kzalloc_obj`, which suggests dynamic allocation, not embedding. This is where I need to be *sure*.

I'm going to revisit `f_midi2_ep_opts_create` to ensure I have a complete picture of the memory allocation scheme. I need to fully understand how these structures are created, initialized, and ultimately, deallocated. I need to make sure I am not missing some details, in particular, what happens to the embedded `group` inside `lun0` when `fsg_opts` is used.



73/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_ep_opts_create]

Results:
map[SourceCode:2497:	/* create a f_midi2_ep_opts instance */
2498:	static int f_midi2_ep_opts_create(struct f_midi2_opts *opts,
2499:					  unsigned int index,
2500:					  struct f_midi2_ep_opts **ep_p)
2501:	{
2502:		struct f_midi2_ep_opts *ep_opts;
2503:	
2504:		ep_opts = kzalloc_obj(*ep_opts);
2505:		if (!ep_opts)
2506:			return -ENOMEM;
2507:	
2508:		ep_opts->opts = opts;
2509:		ep_opts->index = index;
2510:	
2511:		/* set up the default values */
2512:		ep_opts->info.protocol = 2;
2513:		ep_opts->info.protocol_caps = 3;
2514:	
2515:		opts->eps[index] = ep_opts;
2516:		*ep_p = ep_opts;
2517:		return 0;
2518:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

74/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 35591
							output: 26
							thoughts: 566
						

Thoughts:
**Debugging Configfs Refcount Issues in MIDI2 Gadget Driver**

Okay, so I'm looking at this MIDI2 gadget driver and I've got a potential memory leak issue related to how `configfs` handles default groups. I see that the `f_midi2_ep_opts_release` function should be freeing the `f_midi2_ep_opts` structure, specifically allocated memory for the endpoint name and product ID, and the `opts` structure itself.

However, the question is, *does* `configfs` actually decrement the reference count of default groups so that `f_midi2_ep_opts_release` gets called? I need to verify how `config_item_cleanup` behaves because this is where items get released. Looking at `config_item_cleanup` again, I see that it calls the `release` function defined in the `config_item_type`, then decrements the parent and group refcounts using `config_item_put` and `config_group_put` respectively.

Now I'm remembering that `ep_opts` and `block_opts` are added to the `default_groups` list within the `func_inst.group`. When `func_inst.group` is released, does it automatically release the members of `default_groups`? No! Looking at `config_item_cleanup`, I don't see anything that handles releasing the `default_groups`.

So now I'm wondering if `f_midi2_free_inst` is supposed to clean up the default groups. If it does, then the `f_midi2_ep_opts_release` and `f_midi2_block_opts_release` functions might not be needed in the case of default groups.

But that's not quite right... because I also have to account for the possibility of these `ep_opts` and `block_opts` being created dynamically by the user using `mkdir` in configfs. I need to understand what `f_midi2_group_ops` does in relation to cleanup to make sure I'm not missing any reference count management here.



75/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_group_ops]

Results:
map[SourceCode:2624:	static const struct configfs_group_operations f_midi2_group_ops = {
2625:		.make_group	= f_midi2_opts_ep_make,
2626:		.drop_item	= f_midi2_opts_ep_drop,
2627:	};
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

76/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 36759
							output: 28
							thoughts: 13
						

Thoughts:
Okay, here's my summary, taking on the persona you requested:

**Deconstructing `f_midi2_opts_ep_make`**

Right, let's break this down. From what I gather, we're talking about a function, likely in a MIDI 2.0 context, judging by the naming convention. The "f_" prefix usually indicates a function, and "midi2_opts_ep_make" strongly suggests that we're dealing with the creation of something related to MIDI 2.0 options, probably for an endpoint or endpoint configuration. The use of "ep" definitely makes me think "endpoint," which fits perfectly with MIDI's communication model. I'm immediately interested in what "options" means here. Is this dealing with MIDI CI data? Capabilities negotiation? Or perhaps even configuration parameters? I'd need to dig deeper into the actual function definition and the context of its use to determine that precisely. Regardless, the "make" suffix signals that this function is likely responsible for either instantiating or constructing a data structure, or object, to represent these endpoint-specific options. It's probably returning a pointer or handle to this newly created structure, allowing me to interact with it later. I'll need to check for memory allocation and deallocation within this function to ensure there are no obvious memory leaks. I want to see how the inputs are handled, are there default options? And I'll need to know what happens in error cases. Let's see how this thing *works*.



77/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_opts_ep_make]

Results:
map[SourceCode:2520:	/* make_group callback for an EP */
2521:	static struct config_group *
2522:	f_midi2_opts_ep_make(struct config_group *group, const char *name)
2523:	{
2524:		struct f_midi2_opts *opts;
2525:		struct f_midi2_ep_opts *ep_opts;
2526:		unsigned int index;
2527:		int ret;
2528:	
2529:		if (strncmp(name, "ep.", 3))
2530:			return ERR_PTR(-EINVAL);
2531:		ret = kstrtouint(name + 3, 10, &index);
2532:		if (ret)
2533:			return ERR_PTR(ret);
2534:	
2535:		opts = to_f_midi2_opts(&group->cg_item);
2536:		if (index >= MAX_UMP_EPS)
2537:			return ERR_PTR(-EINVAL);
2538:		if (opts->eps[index])
2539:			return ERR_PTR(-EBUSY);
2540:		ret = f_midi2_ep_opts_create(opts, index, &ep_opts);
2541:		if (ret)
2542:			return ERR_PTR(ret);
2543:	
2544:		config_group_init_type_name(&ep_opts->group, name, &f_midi2_ep_type);
2545:		return &ep_opts->group;
2546:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

78/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 37589
							output: 28
							thoughts: 78
						

Thoughts:
Okay, here's my understanding, framed from my perspective as an expert:

**Dynamic Endpoint Option Handling in ConfigFS for MIDI2**

Alright, so the architecture here is that the `ep_opts` structure, which I assume holds all the endpoint-specific configuration options, is created dynamically. This is standard practice in many configfs implementations, offering flexibility. The key point is that its creation is *triggered* by something – likely user interaction with the configfs filesystem. Specifically, the dynamic creation occurs when `configfs_mkdir` calls `f_midi2_opts_ep_make`. This function is responsible for the actual memory allocation for `ep_opts`, and critically, it initializes the reference count to 1. This refcount management is, of course, absolutely crucial to prevent premature freeing.

Now, on the removal side, when the endpoint is no longer needed and is removed (probably via `rmdir` on the configfs entry), `configfs_rmdir` comes into play. It calls the counterpart function, `f_midi2_opts_ep_drop`. This suggests `f_midi2_opts_ep_drop` likely handles decrementing the refcount, and if the count hits zero, it frees the `ep_opts` structure entirely, releasing the memory. Makes sense.
This dynamic allocation/deallocation model, with the associated reference counting, is a pretty common pattern for resource management within a kernel environment like this, especially when dealing with potentially transient configuration objects. We need to be confident that it is being handled right to avoid memory leaks or double frees.



79/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_opts_ep_drop]

Results:
map[SourceCode:2548:	/* drop_item callback for an EP */
2549:	static void
2550:	f_midi2_opts_ep_drop(struct config_group *group, struct config_item *item)
2551:	{
2552:		struct f_midi2_ep_opts *ep_opts = to_f_midi2_ep_opts(item);
2553:	
2554:		mutex_lock(&ep_opts->opts->lock);
2555:		ep_opts->opts->eps[ep_opts->index] = NULL;
2556:		mutex_unlock(&ep_opts->opts->lock);
2557:		config_item_put(item);
2558:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

80/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 38257
							output: 26
							thoughts: 189
						

Thoughts:
**My Investigation into Default Group Destruction in the MIDI2 ConfigFS**

Okay, so I'm digging into this `f_midi2_opts_ep_drop` function, and it's calling `config_item_put(item)`. Standard stuff, that should drop the refcount and trigger `f_midi2_ep_opts_release` to free the item. But wait... there's a wrinkle with the default groups. I know these aren't your typical objects. They're special. I remember now: `configfs_rmdir` returns `-EPERM` for default groups! I quickly recall the code snippet:

```c
	sd = dentry->d_fsdata;
	if (sd->s_type & CONFIGFS_USET_DEFAULT)
		return -EPERM;
```

Essentially, those default groups are never removed directly with an `rmdir` call. So they aren't cleaned up by the usual path. They're only cleaned up when their parent group is taken down. That makes sense, in principle. But then the question hits me: if `config_item_cleanup` isn't dropping their refcount, *who is*? That's the critical question here! I need to trace the object lifetime. I know `config_item_put` handles refcounting, so if its not the direct call, where is it happening? I better check out `f_midi2_free_inst` and see what it's doing. Let's see if that provides any answers.



81/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_free_inst]

Results:
map[SourceCode:2636:	static void f_midi2_free_inst(struct usb_function_instance *f)
2637:	{
2638:		struct f_midi2_opts *opts;
2639:	
2640:		opts = container_of(f, struct f_midi2_opts, func_inst);
2641:	
2642:		kfree(opts->info.iface_name);
2643:		kfree(opts);
2644:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

82/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 38976
							output: 24
							thoughts: 257
						

Thoughts:
**Memory Leak Suspicions in MIDI2 Instance Freeing**

Okay, hold on a second. I'm taking a close look at the `f_midi2_free_inst` function. My initial impression was that it was handling the cleanup, but it appears my understanding was flawed. It seems that `f_midi2_free_inst` *only* frees the `opts` structure and not `ep_opts` and `block_opts`.

Now, if I recall correctly, `ep_opts` and `block_opts` were allocated within `f_midi2_alloc_inst` using `kzalloc_obj`, or something similar.

Looking back at the allocation code in `f_midi2_alloc_inst`, that's correct, `kzalloc_obj` was used for `ep_opts` and `block_opts`. If `f_midi2_free_inst` isn't freeing these, then we have a classic memory leak on our hands! This is a serious problem.

I need to confirm this. Is there anywhere else within this driver that these default group structures are freed? I'm going to quickly check `f_uvc.c` for some clues on how default groups might be handled. It's a related driver and might have similar logic. Need to make sure I don't overlook any subtleties.



83/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:uvc_free_inst]

Results:
map[SourceCode: 904:	static void uvc_free_inst(struct usb_function_instance *f)
 905:	{
 906:		struct f_uvc_opts *opts = fi_to_f_uvc_opts(f);
 907:	
 908:		mutex_destroy(&opts->lock);
 909:		kfree(opts);
 910:	}
 SourceFile:drivers/usb/gadget/function/f_uvc.c]

84/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 39689
							output: 24
							thoughts: 29
						

Thoughts:
Here's my thought process, as if I were analyzing that code:

**Thinking Through Resource Management in `libuvc`**

Okay, hold on a minute. I'm seeing that `uvc_free_inst` is *also* responsible for freeing `opts`. Now, I need to make sure I fully understand the allocation and deallocation lifecycle of these `opts` structures. It seems like the core issue might be where `opts` are allocated.

To confirm my understanding, I'm going to jump over to the `uvc_alloc_inst` function. I need to trace this back. I want to pinpoint the initial allocation and then verify there's no double-freeing or memory leaks happening with this `opts` structure, specifically. Gotta get this straight in my head.



85/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:uvc_alloc_inst]

Results:
map[SourceCode: 912:	static struct usb_function_instance *uvc_alloc_inst(void)
 913:	{
 914:		struct f_uvc_opts *opts;
 915:		struct uvc_camera_terminal_descriptor *cd;
 916:		struct uvc_processing_unit_descriptor *pd;
 917:		struct uvc_output_terminal_descriptor *od;
 918:		struct uvc_descriptor_header **ctl_cls;
 919:		int ret;
 920:	
 921:		opts = kzalloc_obj(*opts);
 922:		if (!opts)
 923:			return ERR_PTR(-ENOMEM);
 924:		opts->func_inst.free_func_inst = uvc_free_inst;
 925:		mutex_init(&opts->lock);
 926:	
 927:		cd = &opts->uvc_camera_terminal;
 928:		cd->bLength			= UVC_DT_CAMERA_TERMINAL_SIZE(3);
 929:		cd->bDescriptorType		= USB_DT_CS_INTERFACE;
 930:		cd->bDescriptorSubType		= UVC_VC_INPUT_TERMINAL;
 931:		cd->bTerminalID			= 1;
 932:		cd->wTerminalType		= cpu_to_le16(0x0201);
 933:		cd->bAssocTerminal		= 0;
 934:		cd->iTerminal			= 0;
 935:		cd->wObjectiveFocalLengthMin	= cpu_to_le16(0);
 936:		cd->wObjectiveFocalLengthMax	= cpu_to_le16(0);
 937:		cd->wOcularFocalLength		= cpu_to_le16(0);
 938:		cd->bControlSize		= 3;
 939:		cd->bmControls[0]		= 2;
 940:		cd->bmControls[1]		= 0;
 941:		cd->bmControls[2]		= 0;
 942:	
 943:		pd = &opts->uvc_processing;
 944:		pd->bLength			= UVC_DT_PROCESSING_UNIT_SIZE(2);
 945:		pd->bDescriptorType		= USB_DT_CS_INTERFACE;
 946:		pd->bDescriptorSubType		= UVC_VC_PROCESSING_UNIT;
 947:		pd->bUnitID			= 2;
 948:		pd->bSourceID			= 1;
 949:		pd->wMaxMultiplier		= cpu_to_le16(16*1024);
 950:		pd->bControlSize		= 2;
 951:		pd->bmControls[0]		= 1;
 952:		pd->bmControls[1]		= 0;
 953:		pd->iProcessing			= 0;
 954:		pd->bmVideoStandards		= 0;
 955:	
 956:		od = &opts->uvc_output_terminal;
 957:		od->bLength			= UVC_DT_OUTPUT_TERMINAL_SIZE;
 958:		od->bDescriptorType		= USB_DT_CS_INTERFACE;
 959:		od->bDescriptorSubType		= UVC_VC_OUTPUT_TERMINAL;
 960:		od->bTerminalID			= 3;
 961:		od->wTerminalType		= cpu_to_le16(0x0101);
 962:		od->bAssocTerminal		= 0;
 963:		od->bSourceID			= 2;
 964:		od->iTerminal			= 0;
 965:	
 966:		/*
 967:		 * With the ability to add XUs to the UVC function graph, we need to be
 968:		 * able to allocate unique unit IDs to them. The IDs are 1-based, with
 969:		 * the CT, PU and OT above consuming the first 3.
 970:		 */
 971:		opts->last_unit_id		= 3;
 972:	
 973:		/* Prepare fs control class descriptors for configfs-based gadgets */
 974:		ctl_cls = opts->uvc_fs_control_cls;
 975:		ctl_cls[0] = NULL;	/* assigned elsewhere by configfs */
 976:		ctl_cls[1] = (struct uvc_descriptor_header *)cd;
 977:		ctl_cls[2] = (struct uvc_descriptor_header *)pd;
 978:		ctl_cls[3] = (struct uvc_descriptor_header *)od;
 979:		ctl_cls[4] = NULL;	/* NULL-terminate */
 980:		opts->fs_control =
 981:			(const struct uvc_descriptor_header * const *)ctl_cls;
 982:	
 983:		/* Prepare hs control class descriptors for configfs-based gadgets */
 984:		ctl_cls = opts->uvc_ss_control_cls;
 985:		ctl_cls[0] = NULL;	/* assigned elsewhere by configfs */
 986:		ctl_cls[1] = (struct uvc_descriptor_header *)cd;
 987:		ctl_cls[2] = (struct uvc_descriptor_header *)pd;
 988:		ctl_cls[3] = (struct uvc_descriptor_header *)od;
 989:		ctl_cls[4] = NULL;	/* NULL-terminate */
 990:		opts->ss_control =
 991:			(const struct uvc_descriptor_header * const *)ctl_cls;
 992:	
 993:		INIT_LIST_HEAD(&opts->extension_units);
 994:	
 995:		opts->streaming_interval = 1;
 996:		opts->streaming_maxpacket = 1024;
 997:		snprintf(opts->function_name, sizeof(opts->function_name), "UVC Camera");
 998:	
 999:		ret = uvcg_attach_configfs(opts);
1000:		if (ret < 0) {
1001:			kfree(opts);
1002:			return ERR_PTR(ret);
1003:		}
1004:	
1005:		return &opts->func_inst;
1006:	}
 SourceFile:drivers/usb/gadget/function/f_uvc.c]

86/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 41681
							output: 25
							thoughts: 13
						

Thoughts:
Okay, let's dive into this. Here's my take on those thoughts, as if they're my own:

**Analyzing `uvcg_attach_configfs`**

Right, let's take a look at `uvcg_attach_configfs`. I'm immediately interested. The name itself suggests a critical function related to attaching something - likely a virtual console device or related resources - to a `configfs` instance. This is core infrastructure stuff. I need to understand the relationship it establishes, the resource management it handles, and any implications for security or performance. My mind immediately begins to formulate potential questions: Does it handle error checking? How does it integrate with the kernel's device model? Is it properly synchronized to handle concurrent requests? And most importantly, how do they handle the attachment/detachment of the ConfigFS mountpoint? Is there proper error handling if the mounting fails? I wonder if there are any race conditions it might introduce? Time to get into the details of the code and the context in which it's used. This feels like an area where subtle bugs can have serious consequences. I hope it has thorough documentation and robust error handling!



87/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:uvcg_attach_configfs]

Results:
map[SourceCode:3822:	int uvcg_attach_configfs(struct f_uvc_opts *opts)
3823:	{
3824:		int ret;
3825:	
3826:		config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name,
3827:					    &uvc_func_type.type);
3828:	
3829:		ret = uvcg_config_create_children(&opts->func_inst.group,
3830:						  &uvc_func_type);
3831:		if (ret < 0)
3832:			config_group_put(&opts->func_inst.group);
3833:	
3834:		return ret;
3835:	}
 SourceFile:drivers/usb/gadget/function/uvc_configfs.c]

88/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 42216
							output: 26
							thoughts: 11
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:

**Navigating the `uvcg_config_create_children` Function**

Alright, let's break down this `uvcg_config_create_children` function. From the name alone, I can infer this is critical for setting up some kind of hierarchical configuration structure, likely related to a *uvcg* – whatever that specific naming convention implies in this context. Immediately, I'm thinking about the data structures involved: are we talking about a tree, a graph, or something more complex? What's the parent-child relationship defined as? Are we dealing with pointers, references, or some form of IDs to manage these connections? I need to understand the underlying model to properly grasp what this function *does*.

My first question will likely be around error handling. What happens if a child creation fails? Does it propagate an error, return a specific code, or log the failure and continue? Understanding the robustness of this function is paramount. I'll need to know about resource management. Does it handle memory allocation and deallocation for the child nodes? Are there any potential memory leaks or race conditions?

I am also thinking about what specific children will be created, and the parameters needed to initialize them. I'll have to consider how those child configs are initialized – are they default values, copied from the parent, or entirely new configurations? I need to understand the implications of default configurations, and how the values are generated.

Next, I'll need to think about the performance implications. How many children are we potentially creating? Is this a recursive operation, or is it iterative? How does the function scale with a large number of children? Are there any optimizations in place to handle large trees efficiently? I'll probably be looking for some kind of benchmark or complexity analysis to gauge the performance characteristics.

Finally, I'll want to trace how this function integrates with the rest of the configuration system. Does it trigger any events, update any internal state, or interact with other modules? I need to understand the broader context to make sure this function behaves correctly within the overall system. In short, it seems this is one of those functions where attention to detail is essential for a robust and performant implementation. I will start by thoroughly analyzing the existing code, and then try to think about some of the edge-case scenarios.



89/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:uvcg_config_create_children]

Results:
map[SourceCode: 138:	static int uvcg_config_create_children(struct config_group *group,
 139:					const struct uvcg_config_group_type *type)
 140:	{
 141:		const struct uvcg_config_group_type **child;
 142:		int ret;
 143:	
 144:		if (type->create_children)
 145:			return type->create_children(group);
 146:	
 147:		for (child = type->children; child && *child; ++child) {
 148:			ret = uvcg_config_create_group(group, *child);
 149:			if (ret < 0)
 150:				return ret;
 151:		}
 152:	
 153:		return 0;
 154:	}
 SourceFile:drivers/usb/gadget/function/uvc_configfs.c]

90/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 43033
							output: 26
							thoughts: 11
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented as if it were my own internal monologue:

**Diving into `uvcg_config_create_group`**

Right, let's break this down. `uvcg_config_create_group`… that's the function responsible for spinning up a new configuration group, right? It's the cornerstone for managing a set of related configurations, crucial for any system that needs to handle multiple, independent (or at least, logically separated) parameter sets. We're talking about the fundamental building block here. So, what are the implicit assumptions? What underlying data structures are being used? Is it relying on a mutex for thread safety, or using some more sophisticated lock-free mechanism? And how is it handling errors? Does it return a status code, throw an exception, or maybe log an error?

I need to understand its relationship to other config modules in this system. Is this a top-level function, or does it call other lower-level config management functions? Does it use a shared global state, or is it isolated to the current process? What's the impact on performance and reliability?

What validation checks are built in? Does it handle invalid group names, or malformed configuration data? What about resource exhaustion? Does it have a good error-handling policy?

I should really run a few scenarios in my head, thinking through different usage patterns. What happens if I try to create a group with a name that already exists? What if the system is under heavy load? Are there any potential race conditions I should be aware of? And most importantly, is this design scalable? Can it handle thousands of config groups without falling apart? Time to dig into the implementation details and make sure things are sound.



91/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:uvcg_config_create_group]

Results:
map[SourceCode: 156:	static int uvcg_config_create_group(struct config_group *parent,
 157:					    const struct uvcg_config_group_type *type)
 158:	{
 159:		struct config_group *group;
 160:	
 161:		group = kzalloc_obj(*group);
 162:		if (!group)
 163:			return -ENOMEM;
 164:	
 165:		config_group_init_type_name(group, type->name, &type->type);
 166:		configfs_add_default_group(group, parent);
 167:	
 168:		return uvcg_config_create_children(group, type);
 169:	}
 SourceFile:drivers/usb/gadget/function/uvc_configfs.c]

92/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 43694
							output: 26
							thoughts: 44
						

Thoughts:
Okay, here's my interpretation of those thoughts, crafted with the perspective of someone deeply familiar with kernel-level memory management:

**Memory Leak Alert: Group Configuration Object**

Alright, hang on a second. I'm staring at this `uvcg_config_create_group` function...and it's *allocating* the `group` structure using `kzalloc_obj`. My spidey senses are tingling. That usually means a chunk of memory is allocated and zeroed out. Good, good. But... where's the corresponding free? `kzalloc_obj` means `kfree_obj` needs to happen eventually. We can't just leave that memory dangling. This smells like a classic memory leak in the making.

Let's not jump to conclusions, though. I need to track down the cleanup procedure for this `group` object. Let's start the hunt for `uvcg_config_item_release`. That’s likely where the object is freed, but I need to make sure!



93/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:uvcg_config_item_release]

Results:
map[SourceCode: 124:	static void uvcg_config_item_release(struct config_item *item)
 125:	{
 126:		struct config_group *group = to_config_group(item);
 127:	
 128:		kfree(group);
 129:	}
 SourceFile:drivers/usb/gadget/function/uvc_configfs.c]

94/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 44102
							output: 26
							thoughts: 89
						

Thoughts:
**Delving into the `uvcg_config_item_release` Rabbit Hole**

Okay, hold on a second! This `uvcg_config_item_release` function... that's the one that actually frees the group, right? It's the key to the cleanup process. But the immediate question that pops into my head is: who's calling *this* function? I need to trace the call chain. Ah, right, it's the release function associated with the item type itself. Makes sense.

But wait a minute... here's a potential snag. If configfs doesn't automatically decrement the reference count of the default groups, then how on earth does `uvcg_config_item_release` even get triggered? There must be some other mechanism at play. Right, I need to investigate the function responsible for removing children. Let's dig into `uvcg_config_remove_children` and see what it reveals. This seems like the most logical next step to understand how that release function is actually called.



95/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:uvcg_config_remove_children]

Results:
map[SourceCode: 171:	static void uvcg_config_remove_children(struct config_group *group)
 172:	{
 173:		struct config_group *child, *n;
 174:	
 175:		list_for_each_entry_safe(child, n, &group->default_groups, group_entry) {
 176:			list_del(&child->group_entry);
 177:			uvcg_config_remove_children(child);
 178:			config_item_put(&child->cg_item);
 179:		}
 180:	}
 SourceFile:drivers/usb/gadget/function/uvc_configfs.c]

96/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 44637
							output: 26
							thoughts: 60
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience:

**Analyzing `uvcg_config_remove_children`**

Right, let me see... I'm looking at this `uvcg_config_remove_children` function, and it seems like it's taking a recursive approach to deleting configuration items. First, it iterates through `default_groups`, removes them – presumably from some internal structure or list – then *recursively* calls itself. The key thing here is, *before* returning up the call stack, after handling the children it then calls `config_item_put(&child->cg_item)`. That seems important for freeing resources associated with the individual config items, likely deallocating memory or releasing references.

The recursion suggests it's dealing with a hierarchical configuration structure, which makes sense. I have to think about what this looks like... a tree-like structure probably, where each node can have child nodes represented in `default_groups`. Now, what I really need to understand is what's the entry point? **Who actually calls this function in the first place**? Understanding the callers will give me a lot of insight into the context and purpose of this whole process. Where is the trigger? Is it triggered by a command? Is it a part of a shutdown procedure? That's what I need to dig into next.



97/2 2026/07/30 14:12 tool codesearch-find-references
0m Args:
map[Name:uvcg_config_remove_children]

Results:
map[References:[map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:uvc_func_item_release SourceFile:drivers/usb/gadget/function/uvc_configfs.c SourceLine:3639] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:uvcg_config_remove_children SourceFile:drivers/usb/gadget/function/uvc_configfs.c SourceLine:177]] TruncatedOutput:false]

98/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 45157
							output: 26
							thoughts: 13
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience, presented in the first person:

**Internal Monologue on `uvc_func_item_release`**

Alright, so `uvc_func_item_release` is being called. That's the key. That function... right. That means we're in the final stages of cleaning up after a UVC function item. The context is crucial here. We're likely dealing with deallocation, resource freeing, potentially removing it from a list or hash table, and generally tidying up the internal structures associated with that particular item. Let me mentally run through the typical scenarios. Is it a descriptor, control, endpoint? Each type has a unique clean-up process, and the specific `release` implementation within the UVC driver will vary depending on the item's role.

We have to make sure there's no dangling pointer, and that any resources allocated by this specific item are freed back to the system. There could be associated mutexes or spinlocks that need to be released to avoid deadlocks. Memory leaks are a definite concern here, and I'll need to double-check that every allocation has a corresponding deallocation. I also hope it's well-synchronized because releasing something with multiple threads can create race conditions very easily, that is the most critical area of concern.

The calling context here is also critical, it will inform my mental checklist, and make sure that this is the correct moment to clear the item. This is generally the last opportunity for this UVC function item to exit gracefully. If there is a problem, the system is going to come to a grinding halt.

Okay, let's trace this call.



99/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:uvc_func_item_release]

Results:
map[SourceCode:3635:	static void uvc_func_item_release(struct config_item *item)
3636:	{
3637:		struct f_uvc_opts *opts = to_f_uvc_opts(item);
3638:	
3639:		uvcg_config_remove_children(to_config_group(item));
3640:		usb_put_function_instance(&opts->func_inst);
3641:	}
 SourceFile:drivers/usb/gadget/function/uvc_configfs.c]

100/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 45715
							output: 26
							thoughts: 43
						

Thoughts:
Okay, here's my take on those thoughts, framed as my own:

**Digging into Refcounting in USB Gadget Drivers**

Right, so I'm looking at this `uvc` driver, and it's making a pretty clear move by explicitly *removing* and *dropping* the reference count of its default groups within its release function. Seems straightforward enough – manage those resources meticulously during the teardown. Now, the question that springs to mind is, what's the story with `f_midi2`? I wonder if it follows the same principle, or if there's a different approach. Let's see... looking into `f_midi2_opts_release`... I expect a similar process to happen, but I need to see to verify.



101/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_opts_release]

Results:
map[SourceCode:2613:	static void f_midi2_opts_release(struct config_item *item)
2614:	{
2615:		struct f_midi2_opts *opts = to_f_midi2_opts(item);
2616:	
2617:		usb_put_function_instance(&opts->func_inst);
2618:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

102/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 46083
							output: 23
							thoughts: 862
						

Thoughts:
**Analyzing a Potential Memory Leak in the ConfigFS Structure**

Okay, here's what's running through my head. I've got this code, and it seems like there might be a memory leak in how these default groups are handled. Specifically, it looks like the refcounts of the default groups aren't being properly dropped when the parent is released.

I'm focusing on these lines:

```c
	config_group_init_type_name(&ep_opts->group, "ep.0",
				    &f_midi2_ep_type);
	configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);

	config_group_init_type_name(&block_opts->group, "block.0",
				    &f_midi2_block_type);
	configfs_add_default_group(&block_opts->group, &ep_opts->group);
```

So, `ep_opts` and `block_opts` are these default groups. `opts->func_inst.group` has `ep_opts->group` as a default group and `ep_opts->group` has `block_opts->group` as a default group. My concern is that when `opts->func_inst.group` gets released - which triggers `f_midi2_opts_release` and eventually `usb_put_function_instance`, freeing `opts` -  `ep_opts` and `block_opts` are left hanging. They're leaked!

Now, how do I fix this?  I have a couple of options.  I could iterate through the `default_groups` and decrement their refcounts, similar to how we handle child removals in `uvcg_config_remove_children`. Or, I could just call `config_item_put` directly on `ep_opts` and `block_opts` in the `f_midi2_free_inst` or `f_midi2_opts_release` functions.

Ah, but wait... where are `ep_opts` and `block_opts` even created?  They are created in the `f_midi2_alloc_inst`:

```c
	/* create the default ep */
	ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
	if (ret) {
		kfree(opts);
		return ERR_PTR(ret);
	}

	/* create the default block */
	ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
	if (ret) {
		kfree(ep_opts);
		kfree(opts);
		return ERR_PTR(ret);
	}
```

Okay, `ep_opts` is stored in `opts->eps[0]` and `block_opts` is stored in `ep_opts->blks[0]`.

But hold on, can there be *other* `ep_opts` and `block_opts` created dynamically? Yes! There's a `make_group` callback, `f_midi2_opts_ep_make`, for EPs.  This gets called by `configfs_mkdir`. When one is created dynamically, refcount is set to 1. When they are removed via `rmdir`, `configfs_rmdir` calls `f_midi2_opts_ep_drop`, which calls `config_item_put(item)`. So dynamically created ones are properly freed when `rmdir` is called.

Here's the key question, though: what happens if the user creates an `ep_opts` dynamically, and then removes the parent group (`opts->func_inst.group`) without removing the dynamic `ep_opts` first?

But wait... configfs doesn't allow removing a directory if it has children!
```c
	ret = sd->s_dependent_count ? -EBUSY : 0;
```
Now, `sd->s_dependent_count` isn't about children. I have to verify that `configfs_rmdir` checks that the directory is empty. I will check `configfs_rmdir` again.



103/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_rmdir]

Results:
map[SourceCode:1469:	static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1470:	{
1471:		struct config_item *parent_item;
1472:		struct config_item *item;
1473:		struct configfs_subsystem *subsys;
1474:		struct configfs_dirent *sd;
1475:		struct configfs_fragment *frag;
1476:		struct module *subsys_owner = NULL, *dead_item_owner = NULL;
1477:		int ret;
1478:	
1479:		sd = dentry->d_fsdata;
1480:		if (sd->s_type & CONFIGFS_USET_DEFAULT)
1481:			return -EPERM;
1482:	
1483:		/* Get a working ref until we have the child */
1484:		parent_item = configfs_get_config_item(dentry->d_parent);
1485:		subsys = to_config_group(parent_item)->cg_subsys;
1486:		BUG_ON(!subsys);
1487:	
1488:		if (!parent_item->ci_type) {
1489:			config_item_put(parent_item);
1490:			return -EINVAL;
1491:		}
1492:	
1493:		/* configfs_mkdir() shouldn't have allowed this */
1494:		BUG_ON(!subsys->su_group.cg_item.ci_type);
1495:		subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
1496:	
1497:		/*
1498:		 * Ensure that no racing symlink() will make detach_prep() fail while
1499:		 * the new link is temporarily attached
1500:		 */
1501:		do {
1502:			struct dentry *wait;
1503:	
1504:			mutex_lock(&configfs_symlink_mutex);
1505:			spin_lock(&configfs_dirent_lock);
1506:			/*
1507:			 * Here's where we check for dependents.  We're protected by
1508:			 * configfs_dirent_lock.
1509:			 * If no dependent, atomically tag the item as dropping.
1510:			 */
1511:			ret = sd->s_dependent_count ? -EBUSY : 0;
1512:			if (!ret) {
1513:				ret = configfs_detach_prep(sd, &wait);
1514:				if (ret)
1515:					configfs_detach_rollback(sd);
1516:			}
1517:			spin_unlock(&configfs_dirent_lock);
1518:			mutex_unlock(&configfs_symlink_mutex);
1519:	
1520:			if (ret) {
1521:				if (ret != -EAGAIN) {
1522:					config_item_put(parent_item);
1523:					return ret;
1524:				}
1525:	
1526:				/* Wait until the racing operation terminates */
1527:				inode_lock(d_inode(wait));
1528:				inode_unlock(d_inode(wait));
1529:				dput(wait);
1530:			}
1531:		} while (ret == -EAGAIN);
1532:	
1533:		frag = sd->s_frag;
1534:		if (down_write_killable(&frag->frag_sem)) {
1535:			spin_lock(&configfs_dirent_lock);
1536:			configfs_detach_rollback(sd);
1537:			spin_unlock(&configfs_dirent_lock);
1538:			config_item_put(parent_item);
1539:			return -EINTR;
1540:		}
1541:		frag->frag_dead = true;
1542:		up_write(&frag->frag_sem);
1543:	
1544:		/* Get a working ref for the duration of this function */
1545:		item = configfs_get_config_item(dentry);
1546:	
1547:		/* Drop reference from above, item already holds one. */
1548:		config_item_put(parent_item);
1549:	
1550:		if (item->ci_type)
1551:			dead_item_owner = item->ci_type->ct_owner;
1552:	
1553:		if (sd->s_type & CONFIGFS_USET_DIR) {
1554:			configfs_detach_group(dentry);
1555:	
1556:			mutex_lock(&subsys->su_mutex);
1557:			client_disconnect_notify(parent_item, item);
1558:			unlink_group(to_config_group(item));
1559:		} else {
1560:			configfs_detach_item(dentry);
1561:	
1562:			mutex_lock(&subsys->su_mutex);
1563:			client_disconnect_notify(parent_item, item);
1564:			unlink_obj(item);
1565:		}
1566:	
1567:		client_drop_item(parent_item, item);
1568:		mutex_unlock(&subsys->su_mutex);
1569:	
1570:		/* Drop our reference from above */
1571:		config_item_put(item);
1572:	
1573:		module_put(dead_item_owner);
1574:		module_put(subsys_owner);
1575:	
1576:		return 0;
1577:	}
 SourceFile:fs/configfs/dir.c]

104/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 49522
							output: 24
							thoughts: 17
						

Thoughts:
Here's my take on the thought process, as if it were my own:

**Ah-ha! A Potential Optimization**

Okay, so I'm digging into this `configfs_detach_prep` function. I was just reviewing the code, and a lightbulb just went off. Hang on a second... is this what I think it is? Yep, there it is! `configfs_detach_prep` explicitly checks if the target directory is empty before proceeding. This is crucial! That emptiness check is practically a free performance optimization waiting to happen. It avoids the overhead of further processing if the detachment is happening on an already-empty directory. I should make a note of this to revisit it later. It might be possible to leverage this check in some higher-level scenarios.



105/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_detach_prep]

Results:
map[SourceCode: 494:	/*
 495:	 * Only subdirectories count here.  Files (CONFIGFS_NOT_PINNED) are
 496:	 * attributes and are removed by rmdir().  We recurse, setting
 497:	 * CONFIGFS_USET_DROPPING on all children that are candidates for
 498:	 * default detach.
 499:	 * If there is an error, the caller will reset the flags via
 500:	 * configfs_detach_rollback().
 501:	 */
 502:	static int configfs_detach_prep(struct configfs_dirent *parent_sd, struct dentry **wait)
 503:	{
 504:		struct configfs_dirent *sd;
 505:		int ret;
 506:	
 507:		/* Mark that we're trying to drop the group */
 508:		parent_sd->s_type |= CONFIGFS_USET_DROPPING;
 509:	
 510:		ret = -EBUSY;
 511:		if (parent_sd->s_links)
 512:			goto out;
 513:	
 514:		ret = 0;
 515:		list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
 516:			if (!sd->s_element ||
 517:			    (sd->s_type & CONFIGFS_NOT_PINNED))
 518:				continue;
 519:			if (sd->s_type & CONFIGFS_USET_DEFAULT) {
 520:				/* Abort if racing with mkdir() */
 521:				if (sd->s_type & CONFIGFS_USET_IN_MKDIR) {
 522:					if (wait)
 523:						*wait= dget(sd->s_dentry);
 524:					return -EAGAIN;
 525:				}
 526:	
 527:				/*
 528:				 * Yup, recursive.  If there's a problem, blame
 529:				 * deep nesting of default_groups
 530:				 */
 531:				ret = configfs_detach_prep(sd, wait);
 532:				if (!ret)
 533:					continue;
 534:			} else
 535:				ret = -ENOTEMPTY;
 536:	
 537:			break;
 538:		}
 539:	
 540:	out:
 541:		return ret;
 542:	}
 SourceFile:fs/configfs/dir.c]

106/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 50455
							output: 28
							thoughts: 662
						

Thoughts:
**Debugging a Potential Resource Leak in the MIDI2 Function Driver**

Okay, so I've been digging into this `configfs` interaction and I think I've found a subtle but potentially critical leak. It seems that `configfs_detach_prep` returns `-ENOTEMPTY` when trying to detach a group that *isn't* a default group, which forces the user to manually remove dynamically created child objects first. The user is supposed to remove the dynamically created `ep_opts` and `block_opts` objects before removing `opts->func_inst.group`. When a dynamically created `ep_opts` is removed, the `f_midi2_opts_ep_drop` function is called, which then invokes `config_item_put(item)`.

However, the handling of *default* groups is different. `configfs_detach_prep` simply recurses into them and sets `CONFIGFS_USET_DROPPING`. Then `configfs_detach_group` removes their dentries, but crucially, it *doesn't* drop their refcount. This means default groups are leaked unless the parent group's release function handles this! Now, this is where things get interesting. In the `uvc` driver, `uvc_func_item_release` correctly handles this by calling `uvcg_config_remove_children`, which *does* drop the refcount of default groups.

But in `f_midi2`, `f_midi2_opts_release` *doesn't* do this! This means we have a resource leak of these default groups. So, I need to figure out where to drop the refcount for these default groups in either `f_midi2_opts_release` or `f_midi2_free_inst`.

Let's see, `ep_opts` and `block_opts` are created in `f_midi2_alloc_inst`. Hmm...

```c
	/* create the default ep */
	ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
	if (ret) {
		kfree(opts);
		return ERR_PTR(ret);
	}

	/* create the default block */
	ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
	if (ret) {
		kfree(ep_opts);
		kfree(opts);
		return ERR_PTR(ret);
	}
```

Could I just call `config_item_put(&ep_opts->group.cg_item)` and `config_item_put(&block_opts->group.cg_item)` in `f_midi2_free_inst` and call it a day?

Wait a second. `ep_opts` is a default group of `opts->func_inst.group`, and `block_opts` is a default group of `ep_opts->group`. If I call `config_item_put(&ep_opts->group.cg_item)`, it'll call `f_midi2_ep_opts_release` which *frees* `ep_opts`. Okay, so far, so good. But that also means `f_midi2_ep_opts_release` frees the `ep_opts`. What about `block_opts`? If `ep_opts` is freed, `block_opts` is still leaked because `f_midi2_ep_opts_release` does not free `block_opts`! I need to investigate `f_midi2_ep_opts_release`.



107/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_ep_opts_release]

Results:
map[SourceCode:2472:	static void f_midi2_ep_opts_release(struct config_item *item)
2473:	{
2474:		struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
2475:	
2476:		kfree(opts->info.ep_name);
2477:		kfree(opts->info.product_id);
2478:		kfree(opts);
2479:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

108/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 52098
							output: 21
							thoughts: 129
						

Thoughts:
**Reflecting on Memory Management in Configuration Structures**

Okay, so I'm looking at this code, and it's clear we're not properly freeing `block_opts` here. That's a definite oversight. Now, let me think...right, `block_opts` *is* essentially a default group within `ep_opts`. This suggests that the function `f_midi2_ep_opts_release` needs to do the same kind of cleanup, dropping the reference count of its default groups, as `uvcg_config_remove_children` does. That seems like the right approach.

Wait, let's step back a moment. `uvcg_config_remove_children` is a general function, it's designed to iterate through the `default_groups` list and decrease the reference count of each of those children. Could we leverage that, or perhaps there is a function in configfs that is designed to do this specific task? The question now is, does `configfs` have a function that directly addresses removing default groups? I need to check.



109/2 2026/07/30 14:12 tool codesearch-find-references
0m Args:
map[Name:default_groups]

Results:
map[References:<nil> TruncatedOutput:false]

110/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 52493
							output: 17
							thoughts: 18
						

Thoughts:
Okay, here's my thought process on that:

**Uh Oh, Wrong Tool! Quick Rethink**

Hang on a second... I think I jumped the gun there. I grabbed the wrong tool for the job, didn't I? Instead of that initial approach, I need to focus on a more direct way to find what I'm looking for. Let's see...I need to quickly locate information related to "default_groups." That's the key term. A good, old-fashioned `grep` should be perfect for this! It'll be a fast and efficient way to scan for those particular strings. Right, `grep` for `default_groups` it is. That should do the trick!



111/2 2026/07/30 14:12 tool grepper
0m Args:
map[Expression:default_groups]

Results:
map[Output:
Full output is too long, showing 500 out of 1221 lines.
Use more precise expression if possible.

Documentation/core-api/kobject.rst=297=kobj_type::
--
Documentation/core-api/kobject.rst-301-            const struct sysfs_ops *sysfs_ops;
Documentation/core-api/kobject.rst:302:            const struct attribute_group **default_groups;
Documentation/core-api/kobject.rst-303-            const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
--
Documentation/core-api/kobject.rst=314=release() method for this type of kobject. The other two fields (sysfs_ops
Documentation/core-api/kobject.rst:315:and default_groups) control how objects of this type are represented in
Documentation/core-api/kobject.rst-316-sysfs; they are beyond the scope of this document.
Documentation/core-api/kobject.rst-317-
Documentation/core-api/kobject.rst:318:The default_groups pointer is a list of default attributes that will be
Documentation/core-api/kobject.rst-319-automatically created for any kobject that is registered with this ktype.
--
Documentation/filesystems/configfs.rst=265=child item::
--
Documentation/filesystems/configfs.rst-270-		struct configfs_subsystem 	*cg_subsys;
Documentation/filesystems/configfs.rst:271:		struct list_head		default_groups;
Documentation/filesystems/configfs.rst-272-		struct list_head		group_entry;
--
Documentation/translations/zh_CN/core-api/kobject.rst=231=kobject_put()以避免错误的发生是一个很好的做法。
--
Documentation/translations/zh_CN/core-api/kobject.rst-260-            const struct sysfs_ops *sysfs_ops;
Documentation/translations/zh_CN/core-api/kobject.rst:261:            const struct attribute_group **default_groups;
Documentation/translations/zh_CN/core-api/kobject.rst-262-            const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
--
Documentation/translations/zh_CN/core-api/kobject.rst=269=kobject_init()或kobject_init_and_add()时必须指定一个指向该结构的
--
Documentation/translations/zh_CN/core-api/kobject.rst-272-当然,kobj_type结构中的release字段是指向这种类型的kobject的release()
Documentation/translations/zh_CN/core-api/kobject.rst:273:方法的一个指针。另外两个字段(sysfs_ops 和 default_groups)控制这种
Documentation/translations/zh_CN/core-api/kobject.rst-274-类型的对象如何在 sysfs 中被表示;它们超出了本文的范围。
Documentation/translations/zh_CN/core-api/kobject.rst-275-
Documentation/translations/zh_CN/core-api/kobject.rst:276:default_groups 指针是一个默认属性的列表,它将为任何用这个 ktype 注册
Documentation/translations/zh_CN/core-api/kobject.rst-277-的 kobject 自动创建。
--
arch/powerpc/kernel/cacheinfo.c=709=static struct kobj_attribute cache_shared_cpu_list_attr =
--
arch/powerpc/kernel/cacheinfo.c-712-/* Attributes which should always be created -- the kobject/sysfs core
arch/powerpc/kernel/cacheinfo.c:713: * does this automatically via kobj_type->default_groups.  This is the
arch/powerpc/kernel/cacheinfo.c-714- * minimum data required to uniquely identify a cache.
--
arch/powerpc/kernel/cacheinfo.c=739=static const struct kobj_type cache_index_type = {
--
arch/powerpc/kernel/cacheinfo.c-741-	.sysfs_ops = &cache_index_ops,
arch/powerpc/kernel/cacheinfo.c:742:	.default_groups = cache_index_default_groups,
arch/powerpc/kernel/cacheinfo.c-743-};
--
arch/powerpc/kernel/secvar-sysfs.c=129=static const struct kobj_type secvar_ktype = {
arch/powerpc/kernel/secvar-sysfs.c-130-	.sysfs_ops	= &kobj_sysfs_ops,
arch/powerpc/kernel/secvar-sysfs.c:131:	.default_groups = secvar_attr_groups,
arch/powerpc/kernel/secvar-sysfs.c-132-};
--
arch/powerpc/platforms/powernv/opal-dump.c=214=static const struct kobj_type dump_ktype = {
--
arch/powerpc/platforms/powernv/opal-dump.c-216-	.release = &dump_release,
arch/powerpc/platforms/powernv/opal-dump.c:217:	.default_groups = dump_default_groups,
arch/powerpc/platforms/powernv/opal-dump.c-218-};
--
arch/powerpc/platforms/powernv/opal-elog.c=148=static const struct kobj_type elog_ktype = {
--
arch/powerpc/platforms/powernv/opal-elog.c-150-	.release = &elog_release,
arch/powerpc/platforms/powernv/opal-elog.c:151:	.default_groups = elog_default_groups,
arch/powerpc/platforms/powernv/opal-elog.c-152-};
--
arch/powerpc/platforms/pseries/vas-sysfs.c=166=static const struct kobj_type vas_def_attr_type = {
--
arch/powerpc/platforms/pseries/vas-sysfs.c-168-		.sysfs_ops      =       &vas_sysfs_ops,
arch/powerpc/platforms/pseries/vas-sysfs.c:169:		.default_groups	=	vas_def_capab_groups,
arch/powerpc/platforms/pseries/vas-sysfs.c-170-};
--
arch/powerpc/platforms/pseries/vas-sysfs.c=172=static const struct kobj_type vas_qos_attr_type = {
--
arch/powerpc/platforms/pseries/vas-sysfs.c-174-		.sysfs_ops	=	&vas_sysfs_ops,
arch/powerpc/platforms/pseries/vas-sysfs.c:175:		.default_groups	=	vas_qos_capab_groups,
arch/powerpc/platforms/pseries/vas-sysfs.c-176-};
--
arch/sh/kernel/cpu/sh4/sq.c=334=static struct kobj_type ktype_percpu_entry = {
arch/sh/kernel/cpu/sh4/sq.c-335-	.sysfs_ops	= &sq_sysfs_ops,
arch/sh/kernel/cpu/sh4/sq.c:336:	.default_groups	= sq_sysfs_groups,
arch/sh/kernel/cpu/sh4/sq.c-337-};
--
arch/x86/kernel/cpu/mce/amd.c=1038=static const struct kobj_type threshold_ktype = {
arch/x86/kernel/cpu/mce/amd.c-1039-	.sysfs_ops		= &threshold_ops,
arch/x86/kernel/cpu/mce/amd.c:1040:	.default_groups		= default_groups,
arch/x86/kernel/cpu/mce/amd.c-1041-	.release		= threshold_block_release,
--
arch/x86/platform/efi/runtime-map.c=96=static const struct kobj_type __refconst map_ktype = {
arch/x86/platform/efi/runtime-map.c-97-	.sysfs_ops	= &map_attr_ops,
arch/x86/platform/efi/runtime-map.c:98:	.default_groups	= def_groups,
arch/x86/platform/efi/runtime-map.c-99-	.release	= map_release,
--
block/blk-crypto-sysfs.c=154=static const struct kobj_type blk_crypto_ktype = {
block/blk-crypto-sysfs.c:155:	.default_groups = blk_crypto_attr_groups,
block/blk-crypto-sysfs.c-156-	.sysfs_ops	= &blk_crypto_attr_ops,
--
block/blk-ia-ranges.c=78=static const struct kobj_type blk_ia_range_ktype = {
block/blk-ia-ranges.c-79-	.sysfs_ops	= &blk_ia_range_sysfs_ops,
block/blk-ia-ranges.c:80:	.default_groups	= blk_ia_range_groups,
block/blk-ia-ranges.c-81-	.release	= blk_ia_range_sysfs_nop_release,
--
block/blk-mq-sysfs.c=137=static const struct kobj_type blk_mq_hw_ktype = {
block/blk-mq-sysfs.c-138-	.sysfs_ops	= &blk_mq_hw_sysfs_ops,
block/blk-mq-sysfs.c:139:	.default_groups = default_hw_ctx_groups,
block/blk-mq-sysfs.c-140-	.release	= blk_mq_hw_sysfs_release,
--
block/blk-sysfs.c=925=const struct kobj_type blk_queue_ktype = {
block/blk-sysfs.c:926:	.default_groups = blk_queue_attr_groups,
block/blk-sysfs.c-927-	.sysfs_ops	= &queue_sysfs_ops,
--
drivers/acpi/cppc_acpi.c=234=static const struct kobj_type cppc_ktype = {
drivers/acpi/cppc_acpi.c-235-	.sysfs_ops = &kobj_sysfs_ops,
drivers/acpi/cppc_acpi.c:236:	.default_groups = cppc_groups,
drivers/acpi/cppc_acpi.c-237-};
--
drivers/acpi/device_sysfs.c=81=static const struct kobj_type acpi_data_node_ktype = {
drivers/acpi/device_sysfs.c-82-	.sysfs_ops = &acpi_data_node_sysfs_ops,
drivers/acpi/device_sysfs.c:83:	.default_groups = acpi_data_node_default_groups,
drivers/acpi/device_sysfs.c-84-	.release = acpi_data_node_release,
--
drivers/acpi/sysfs.c=973=static const struct kobj_type acpi_hotplug_profile_ktype = {
drivers/acpi/sysfs.c-974-	.sysfs_ops = &kobj_sysfs_ops,
drivers/acpi/sysfs.c:975:	.default_groups = hotplug_profile_groups,
drivers/acpi/sysfs.c-976-};
--
drivers/base/cacheinfo.c=836=static const struct attribute_group cache_default_group = {
--
drivers/base/cacheinfo.c-840-
drivers/base/cacheinfo.c:841:static const struct attribute_group *cache_default_groups[] = {
drivers/base/cacheinfo.c-842-	&cache_default_group,
--
drivers/base/cacheinfo.c=859=cache_get_attribute_groups(struct cacheinfo *this_leaf)
--
drivers/base/cacheinfo.c-864-	if (!priv_group)
drivers/base/cacheinfo.c:865:		return cache_default_groups;
drivers/base/cacheinfo.c-866-
--
drivers/block/rnbd/rnbd-clt-sysfs.c=485=static const struct kobj_type rnbd_dev_ktype = {
drivers/block/rnbd/rnbd-clt-sysfs.c-486-	.sysfs_ops      = &kobj_sysfs_ops,
drivers/block/rnbd/rnbd-clt-sysfs.c:487:	.default_groups = rnbd_dev_groups,
drivers/block/rnbd/rnbd-clt-sysfs.c-488-	.release	= rnbd_dev_release,
--
drivers/cpufreq/cpufreq.c=1021=static const struct kobj_type ktype_cpufreq = {
drivers/cpufreq/cpufreq.c-1022-	.sysfs_ops	= &sysfs_ops,
drivers/cpufreq/cpufreq.c:1023:	.default_groups	= cpufreq_groups,
drivers/cpufreq/cpufreq.c-1024-	.release	= cpufreq_sysfs_release,
--
drivers/cpufreq/cpufreq_conservative.c=317=static struct dbs_governor cs_governor = {
drivers/cpufreq/cpufreq_conservative.c-318-	.gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("conservative"),
drivers/cpufreq/cpufreq_conservative.c:319:	.kobj_type = { .default_groups = cs_groups },
drivers/cpufreq/cpufreq_conservative.c-320-	.gov_dbs_update = cs_dbs_update,
--
drivers/cpufreq/cpufreq_ondemand.c=375=static struct dbs_governor od_dbs_gov = {
drivers/cpufreq/cpufreq_ondemand.c-376-	.gov = CPUFREQ_DBS_GOVERNOR_INITIALIZER("ondemand"),
drivers/cpufreq/cpufreq_ondemand.c:377:	.kobj_type = { .default_groups = od_groups },
drivers/cpufreq/cpufreq_ondemand.c-378-	.gov_dbs_update = od_dbs_update,
--
drivers/cpuidle/sysfs.c=457=static const struct kobj_type ktype_state_cpuidle = {
drivers/cpuidle/sysfs.c-458-	.sysfs_ops = &cpuidle_state_sysfs_ops,
drivers/cpuidle/sysfs.c:459:	.default_groups = cpuidle_state_default_groups,
drivers/cpuidle/sysfs.c-460-	.release = cpuidle_state_sysfs_release,
--
drivers/cpuidle/sysfs.c=604=static const struct kobj_type ktype_driver_cpuidle = {
drivers/cpuidle/sysfs.c-605-	.sysfs_ops = &cpuidle_driver_sysfs_ops,
drivers/cpuidle/sysfs.c:606:	.default_groups = cpuidle_driver_default_groups,
drivers/cpuidle/sysfs.c-607-	.release = cpuidle_driver_sysfs_release,
--
drivers/dma/ioat/sysfs.c=169=const struct kobj_type ioat_ktype = {
drivers/dma/ioat/sysfs.c-170-	.sysfs_ops = &ioat_sysfs_ops,
drivers/dma/ioat/sysfs.c:171:	.default_groups = ioat_groups,
drivers/dma/ioat/sysfs.c-172-};
--
drivers/edac/edac_device_sysfs.c=213=static struct kobj_type ktype_device_ctrl = {
--
drivers/edac/edac_device_sysfs.c-215-	.sysfs_ops = &device_ctl_info_ops,
drivers/edac/edac_device_sysfs.c:216:	.default_groups = device_ctrl_groups,
drivers/edac/edac_device_sysfs.c-217-};
--
drivers/edac/edac_device_sysfs.c=398=static struct kobj_type ktype_instance_ctrl = {
--
drivers/edac/edac_device_sysfs.c-400-	.sysfs_ops = &device_instance_ops,
drivers/edac/edac_device_sysfs.c:401:	.default_groups = device_instance_groups,
drivers/edac/edac_device_sysfs.c-402-};
--
drivers/edac/edac_device_sysfs.c=481=static struct kobj_type ktype_block_ctrl = {
--
drivers/edac/edac_device_sysfs.c-483-	.sysfs_ops = &device_block_ops,
drivers/edac/edac_device_sysfs.c:484:	.default_groups = device_block_groups,
drivers/edac/edac_device_sysfs.c-485-};
--
drivers/edac/edac_pci_sysfs.c=146=static struct kobj_type ktype_pci_instance = {
--
drivers/edac/edac_pci_sysfs.c-148-	.sysfs_ops = &pci_instance_ops,
drivers/edac/edac_pci_sysfs.c:149:	.default_groups = pci_instance_groups,
drivers/edac/edac_pci_sysfs.c-150-};
--
drivers/edac/edac_pci_sysfs.c=329=static struct kobj_type ktype_edac_pci_main_kobj = {
--
drivers/edac/edac_pci_sysfs.c-331-	.sysfs_ops = &edac_pci_sysfs_ops,
drivers/edac/edac_pci_sysfs.c:332:	.default_groups = edac_pci_groups,
drivers/edac/edac_pci_sysfs.c-333-};
--
drivers/firmware/dmi-sysfs.c=307=static const struct kobj_type dmi_system_event_log_ktype = {
--
drivers/firmware/dmi-sysfs.c-309-	.sysfs_ops = &dmi_sysfs_specialize_attr_ops,
drivers/firmware/dmi-sysfs.c:310:	.default_groups = dmi_sysfs_sel_groups,
drivers/firmware/dmi-sysfs.c-311-};
--
drivers/firmware/dmi-sysfs.c=564=static const struct kobj_type dmi_sysfs_entry_ktype = {
--
drivers/firmware/dmi-sysfs.c-566-	.sysfs_ops = &dmi_sysfs_attr_ops,
drivers/firmware/dmi-sysfs.c:567:	.default_groups = dmi_sysfs_entry_groups,
drivers/firmware/dmi-sysfs.c-568-};
--
drivers/firmware/efi/esrt.c=153=static const struct kobj_type esre1_ktype = {
--
drivers/firmware/efi/esrt.c-155-	.sysfs_ops = &esre_attr_ops,
drivers/firmware/efi/esrt.c:156:	.default_groups = esre1_groups,
drivers/firmware/efi/esrt.c-157-};
--
drivers/firmware/memmap.c=119=static const struct kobj_type memmap_ktype = {
--
drivers/firmware/memmap.c-121-	.sysfs_ops	= &memmap_attr_ops,
drivers/firmware/memmap.c:122:	.default_groups	= def_groups,
drivers/firmware/memmap.c-123-};
--
drivers/firmware/qemu_fw_cfg.c=454=static const struct kobj_type fw_cfg_sysfs_entry_ktype = {
drivers/firmware/qemu_fw_cfg.c:455:	.default_groups = fw_cfg_sysfs_entry_groups,
drivers/firmware/qemu_fw_cfg.c-456-	.sysfs_ops = &fw_cfg_sysfs_attr_ops,
--
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c=1016=static const struct kobj_type ip_hw_instance_ktype = {
--
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c-1018-	.sysfs_ops = &ip_hw_instance_sysfs_ops,
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1019:	.default_groups = ip_hw_instance_groups,
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c-1020-};
--
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c=1098=static const struct kobj_type ip_die_entry_ktype = {
--
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c-1100-	.sysfs_ops = &ip_die_entry_sysfs_ops,
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c:1101:	.default_groups = ip_die_entry_groups,
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c-1102-};
--
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c=773=static const struct kobj_type xcp_cfg_res_sysfs_ktype = {
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c-774-	.sysfs_ops = &xcp_cfg_res_sysfs_ops,
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c:775:	.default_groups = xcp_cfg_res_sysfs_groups,
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c-776-};
--
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c=440=static const struct kobj_type amdgpu_xgmi_hive_type = {
--
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c-442-	.sysfs_ops = &amdgpu_xgmi_hive_ops,
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c:443:	.default_groups = amdgpu_xgmi_hive_groups,
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c-444-};
--
drivers/gpu/drm/amd/amdkfd/kfd_process.c=497=static const struct kobj_type procfs_queue_type = {
drivers/gpu/drm/amd/amdkfd/kfd_process.c-498-	.sysfs_ops = &procfs_queue_ops,
drivers/gpu/drm/amd/amdkfd/kfd_process.c:499:	.default_groups = procfs_queue_groups,
drivers/gpu/drm/amd/amdkfd/kfd_process.c-500-};
--
drivers/gpu/drm/i915/gt/intel_gt_sysfs.c=75=static const struct kobj_type kobj_gt_type = {
--
drivers/gpu/drm/i915/gt/intel_gt_sysfs.c-77-	.sysfs_ops = &kobj_sysfs_ops,
drivers/gpu/drm/i915/gt/intel_gt_sysfs.c:78:	.default_groups = id_groups,
drivers/gpu/drm/i915/gt/intel_gt_sysfs.c-79-};
--
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c=484=static const struct kobj_type xe_sriov_dev_ktype = {
--
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c-486-	.sysfs_ops = &xe_sriov_dev_sysfs_ops,
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c:487:	.default_groups = xe_sriov_dev_attr_groups,
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c-488-};
--
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c=490=static const struct kobj_type xe_sriov_vf_ktype = {
--
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c-492-	.sysfs_ops = &xe_sriov_vf_sysfs_ops,
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c:493:	.default_groups = xe_sriov_vf_attr_groups,
drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c-494-};
--
drivers/infiniband/core/cma_configfs.c=318=static void drop_cma_dev(struct config_group *cgroup, struct config_item *item)
--
drivers/infiniband/core/cma_configfs.c-324-
drivers/infiniband/core/cma_configfs.c:325:	configfs_remove_default_groups(&cma_dev_group->ports_group);
drivers/infiniband/core/cma_configfs.c:326:	configfs_remove_default_groups(&cma_dev_group->device_group);
drivers/infiniband/core/cma_configfs.c-327-	config_item_put(item);
--
drivers/infiniband/core/sysfs.c=727=static struct kobj_type port_type = {
--
drivers/infiniband/core/sysfs.c-729-	.sysfs_ops     = &port_sysfs_ops,
drivers/infiniband/core/sysfs.c:730:	.default_groups = port_default_groups,
drivers/infiniband/core/sysfs.c-731-};
--
drivers/infiniband/hw/usnic/usnic_ib_sysfs.c=247=static struct kobj_type usnic_ib_qpn_type = {
drivers/infiniband/hw/usnic/usnic_ib_sysfs.c-248-	.sysfs_ops = &usnic_ib_qpn_sysfs_ops,
drivers/infiniband/hw/usnic/usnic_ib_sysfs.c:249:	.default_groups = usnic_ib_qpn_default_groups,
drivers/infiniband/hw/usnic/usnic_ib_sysfs.c-250-};
--
drivers/md/bcache/sysfs.h=6=const struct kobj_type type ## _ktype = {					\
--
drivers/md/bcache/sysfs.h-11-	}),								\
drivers/md/bcache/sysfs.h:12:	.default_groups	= type ## _groups				\
drivers/md/bcache/sysfs.h-13-}
--
drivers/md/dm-sysfs.c=119=static const struct kobj_type dm_ktype = {
drivers/md/dm-sysfs.c-120-	.sysfs_ops	= &dm_sysfs_ops,
drivers/md/dm-sysfs.c:121:	.default_groups	= dm_groups,
drivers/md/dm-sysfs.c-122-	.release	= dm_kobject_release,
--
drivers/md/md.c=3785=static const struct kobj_type rdev_ktype = {
--
drivers/md/md.c-3787-	.sysfs_ops	= &rdev_sysfs_ops,
drivers/md/md.c:3788:	.default_groups	= rdev_default_groups,
drivers/md/md.c-3789-};
--
drivers/md/md.c=6170=static const struct kobj_type md_ktype = {
--
drivers/md/md.c-6172-	.sysfs_ops	= &md_sysfs_ops,
drivers/md/md.c:6173:	.default_groups	= md_default_groups,
drivers/md/md.c-6174-};
--
drivers/net/ethernet/ibm/ibmveth.c=2127=static struct kobj_type ktype_veth_pool = {
--
drivers/net/ethernet/ibm/ibmveth.c-2129-	.sysfs_ops      = &veth_pool_ops,
drivers/net/ethernet/ibm/ibmveth.c:2130:	.default_groups = veth_pool_groups,
drivers/net/ethernet/ibm/ibmveth.c-2131-};
--
drivers/parisc/pdc_stable.c=486=static const struct kobj_type ktype_pdcspath = {
drivers/parisc/pdc_stable.c-487-	.sysfs_ops = &pdcspath_attr_ops,
drivers/parisc/pdc_stable.c:488:	.default_groups = paths_subsys_groups,
drivers/parisc/pdc_stable.c-489-};
--
drivers/pci/slot.c=110=static const struct attribute_group pci_slot_default_group = {
--
drivers/pci/slot.c-113-
drivers/pci/slot.c:114:static const struct attribute_group *pci_slot_default_groups[] = {
drivers/pci/slot.c-115-	&pci_slot_default_group,
--
drivers/pci/slot.c=122=static const struct kobj_type pci_slot_ktype = {
--
drivers/pci/slot.c-124-	.release = &pci_slot_release,
drivers/pci/slot.c:125:	.default_groups = pci_slot_default_groups,
drivers/pci/slot.c-126-};
--
drivers/platform/x86/intel/pmt/discovery.c=282=static const struct kobj_type pmt_feature_rmid_ktype = {
--
drivers/platform/x86/intel/pmt/discovery.c-284-	.release = pmt_feature_release,
drivers/platform/x86/intel/pmt/discovery.c:285:	.default_groups = pmt_feature_rmid_groups,
drivers/platform/x86/intel/pmt/discovery.c-286-};
--
drivers/platform/x86/intel/pmt/discovery.c=298=static const struct kobj_type pmt_feature_watcher_ktype = {
--
drivers/platform/x86/intel/pmt/discovery.c-300-	.release = pmt_feature_release,
drivers/platform/x86/intel/pmt/discovery.c:301:	.default_groups = pmt_feature_watcher_groups,
drivers/platform/x86/intel/pmt/discovery.c-302-};
--
drivers/platform/x86/intel/pmt/discovery.c=313=static const struct kobj_type pmt_feature_command_ktype = {
--
drivers/platform/x86/intel/pmt/discovery.c-315-	.release = pmt_feature_release,
drivers/platform/x86/intel/pmt/discovery.c:316:	.default_groups = pmt_feature_command_groups,
drivers/platform/x86/intel/pmt/discovery.c-317-};
--
drivers/platform/x86/intel/pmt/discovery.c=326=static const struct kobj_type pmt_feature_guids_ktype = {
--
drivers/platform/x86/intel/pmt/discovery.c-328-	.release = pmt_feature_release,
drivers/platform/x86/intel/pmt/discovery.c:329:	.default_groups = pmt_feature_guids_groups,
drivers/platform/x86/intel/pmt/discovery.c-330-};
--
drivers/platform/x86/lenovo/think-lmi.c=1264=static const struct kobj_type tlmi_attr_setting_ktype = {
--
drivers/platform/x86/lenovo/think-lmi.c-1266-	.sysfs_ops	= &kobj_sysfs_ops,
drivers/platform/x86/lenovo/think-lmi.c:1267:	.default_groups = tlmi_attr_groups,
drivers/platform/x86/lenovo/think-lmi.c-1268-};
--
drivers/platform/x86/lenovo/think-lmi.c=1270=static const struct kobj_type tlmi_pwd_setting_ktype = {
--
drivers/platform/x86/lenovo/think-lmi.c-1272-	.sysfs_ops	= &kobj_sysfs_ops,
drivers/platform/x86/lenovo/think-lmi.c:1273:	.default_groups = auth_attr_groups,
drivers/platform/x86/lenovo/think-lmi.c-1274-};
--
drivers/platform/x86/uv_sysfs.c=207=static const struct kobj_type hub_attr_type = {
--
drivers/platform/x86/uv_sysfs.c-209-	.sysfs_ops	= &hub_sysfs_ops,
drivers/platform/x86/uv_sysfs.c:210:	.default_groups	= uv_hub_groups,
drivers/platform/x86/uv_sysfs.c-211-};
--
drivers/platform/x86/uv_sysfs.c=359=static const struct kobj_type uv_port_attr_type = {
--
drivers/platform/x86/uv_sysfs.c-361-	.sysfs_ops	= &uv_port_sysfs_ops,
drivers/platform/x86/uv_sysfs.c:362:	.default_groups	= uv_port_groups,
drivers/platform/x86/uv_sysfs.c-363-};
--
drivers/power/supply/ab8500_fg.c=2533=static const struct kobj_type ab8500_fg_ktype = {
drivers/power/supply/ab8500_fg.c-2534-	.sysfs_ops = &ab8500_fg_sysfs_ops,
drivers/power/supply/ab8500_fg.c:2535:	.default_groups = ab8500_fg_groups,
drivers/power/supply/ab8500_fg.c-2536-};
--
drivers/s390/block/dasd_devmap.c=2535=static struct kobj_type path_attr_type = {
drivers/s390/block/dasd_devmap.c-2536-	.release	= dasd_path_release,
drivers/s390/block/dasd_devmap.c:2537:	.default_groups	= paths_info_groups,
drivers/s390/block/dasd_devmap.c-2538-	.sysfs_ops	= &kobj_sysfs_ops,
--
drivers/s390/char/sclp_sd.c=456=static struct kobj_type sclp_sd_file_ktype = {
--
drivers/s390/char/sclp_sd.c-458-	.release = sclp_sd_file_release,
drivers/s390/char/sclp_sd.c:459:	.default_groups = sclp_sd_file_default_groups,
drivers/s390/char/sclp_sd.c-460-};
--
drivers/soc/hisilicon/kunpeng_hccs.c=1040=static const struct kobj_type hccs_port_type = {
drivers/soc/hisilicon/kunpeng_hccs.c-1041-	.sysfs_ops = &hccs_comm_ops,
drivers/soc/hisilicon/kunpeng_hccs.c:1042:	.default_groups = hccs_port_default_groups,
drivers/soc/hisilicon/kunpeng_hccs.c-1043-};
--
drivers/soc/hisilicon/kunpeng_hccs.c=1112=static const struct kobj_type hccs_die_type = {
drivers/soc/hisilicon/kunpeng_hccs.c-1113-	.sysfs_ops = &hccs_comm_ops,
drivers/soc/hisilicon/kunpeng_hccs.c:1114:	.default_groups = hccs_die_default_groups,
drivers/soc/hisilicon/kunpeng_hccs.c-1115-};
--
drivers/soc/hisilicon/kunpeng_hccs.c=1215=static const struct kobj_type hccs_chip_type = {
drivers/soc/hisilicon/kunpeng_hccs.c-1216-	.sysfs_ops = &hccs_comm_ops,
drivers/soc/hisilicon/kunpeng_hccs.c:1217:	.default_groups = hccs_chip_default_groups,
drivers/soc/hisilicon/kunpeng_hccs.c-1218-};
--
drivers/staging/greybus/audio_manager_module.c=146=static const struct kobj_type gb_audio_module_type = {
--
drivers/staging/greybus/audio_manager_module.c-148-	.release = gb_audio_module_release,
drivers/staging/greybus/audio_manager_module.c:149:	.default_groups = gb_audio_module_default_groups,
drivers/staging/greybus/audio_manager_module.c-150-};
--
drivers/target/target_core_configfs.c=267=static void target_core_deregister_fabric(
--
drivers/target/target_core_configfs.c-283-
drivers/target/target_core_configfs.c:284:	configfs_remove_default_groups(&tf->tf_group);
drivers/target/target_core_configfs.c-285-	config_item_put(item);
--
drivers/target/target_core_configfs.c=3422=static struct config_group *target_core_make_subdev(
--
drivers/target/target_core_configfs.c-3485-	 */
drivers/target/target_core_configfs.c:3486:	target_stat_setup_dev_default_groups(dev);
drivers/target/target_core_configfs.c-3487-
--
drivers/target/target_core_configfs.c=3502=static void target_core_drop_subdev(
--
drivers/target/target_core_configfs.c-3514-
drivers/target/target_core_configfs.c:3515:	configfs_remove_default_groups(&dev->dev_stat_grps.stat_group);
drivers/target/target_core_configfs.c:3516:	configfs_remove_default_groups(&dev->t10_alua.alua_tg_pt_gps_group);
drivers/target/target_core_configfs.c-3517-
--
drivers/target/target_core_configfs.c-3523-
drivers/target/target_core_configfs.c:3524:	configfs_remove_default_groups(dev_cg);
drivers/target/target_core_configfs.c-3525-
--
drivers/target/target_core_configfs.c=3843=static void __exit target_core_exit_configfs(void)
drivers/target/target_core_configfs.c-3844-{
drivers/target/target_core_configfs.c:3845:	configfs_remove_default_groups(&alua_lu_gps_group);
drivers/target/target_core_configfs.c:3846:	configfs_remove_default_groups(&alua_group);
drivers/target/target_core_configfs.c:3847:	configfs_remove_default_groups(&target_core_hbagroup);
drivers/target/target_core_configfs.c-3848-
drivers/target/target_core_configfs.c-3849-	/*
drivers/target/target_core_configfs.c:3850:	 * We expect subsys->su_group.default_groups to be released
drivers/target/target_core_configfs.c-3851-	 * by configfs subsystem provider logic..
--
drivers/target/target_core_fabric_configfs.c=265=static struct config_group *target_fabric_make_mappedlun(
--
drivers/target/target_core_fabric_configfs.c-315-
drivers/target/target_core_fabric_configfs.c:316:	target_stat_setup_mappedlun_default_groups(lacl);
drivers/target/target_core_fabric_configfs.c-317-
--
drivers/target/target_core_fabric_configfs.c=326=static void target_fabric_drop_mappedlun(
--
drivers/target/target_core_fabric_configfs.c-332-
drivers/target/target_core_fabric_configfs.c:333:	configfs_remove_default_groups(&lacl->ml_stat_grps.stat_group);
drivers/target/target_core_fabric_configfs.c:334:	configfs_remove_default_groups(&lacl->se_lun_group);
drivers/target/target_core_fabric_configfs.c-335-
--
drivers/target/target_core_fabric_configfs.c=339=static void target_fabric_nacl_base_release(struct config_item *item)
--
drivers/target/target_core_fabric_configfs.c-343-
drivers/target/target_core_fabric_configfs.c:344:	configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
drivers/target/target_core_fabric_configfs.c-345-	core_tpg_del_initiator_node_acl(se_nacl);
--
drivers/target/target_core_fabric_configfs.c=357=TF_CIT_SETUP_DRV(tpg_nacl_base, &target_fabric_nacl_base_item_ops,
--
drivers/target/target_core_fabric_configfs.c-364- * This is used as a placeholder for struct se_node_acl->acl_fabric_stat_group
drivers/target/target_core_fabric_configfs.c:365: * to allow fabrics access to ->acl_fabric_stat_group->default_groups[]
drivers/target/target_core_fabric_configfs.c-366- */
--
drivers/target/target_core_fabric_configfs.c=373=static struct config_group *target_fabric_make_nodeacl(
--
drivers/target/target_core_fabric_configfs.c-411-		if (ret) {
drivers/target/target_core_fabric_configfs.c:412:			configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
drivers/target/target_core_fabric_configfs.c-413-			core_tpg_del_initiator_node_acl(se_nacl);
--
drivers/target/target_core_fabric_configfs.c=421=static void target_fabric_drop_nodeacl(
--
drivers/target/target_core_fabric_configfs.c-427-
drivers/target/target_core_fabric_configfs.c:428:	configfs_remove_default_groups(&se_nacl->acl_group);
drivers/target/target_core_fabric_configfs.c-429-
--
drivers/target/target_core_fabric_configfs.c=740=static struct config_group *target_fabric_make_lun(
--
drivers/target/target_core_fabric_configfs.c-771-
drivers/target/target_core_fabric_configfs.c:772:	target_stat_setup_port_default_groups(lun);
drivers/target/target_core_fabric_configfs.c-773-
--
drivers/target/target_core_fabric_configfs.c=777=static void target_fabric_drop_lun(

]

112/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 64481
							output: 26
							thoughts: 22
						

Thoughts:
Here's my take on the thought process, tailored for an expert audience:

**Investigating `configfs_remove_default_groups`**

Okay, good news! `configfs_remove_default_groups` is definitely a thing. I remember vaguely, or maybe I've seen it in some other context, so that's a positive start. Now, the natural next step is to dive right into its definition. I need to understand its exact purpose within the configfs framework, the arguments it takes, and of course, what side effects it might introduce. I'll need to look at how it interacts with the broader namespace logic, file permissions, and perhaps the handling of group membership within the virtual filesystem. My focus now will be its precise function and relationship to the overall configuration management process. Understanding this will be critical to the immediate task.



113/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:configfs_remove_default_groups]

Results:
map[SourceCode: 748:	void configfs_remove_default_groups(struct config_group *group)
 749:	{
 750:		struct config_group *g, *n;
 751:	
 752:		list_for_each_entry_safe(g, n, &group->default_groups, group_entry) {
 753:			list_del(&g->group_entry);
 754:			config_item_put(&g->cg_item);
 755:		}
 756:	}
 SourceFile:fs/configfs/dir.c]

114/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 64879
							output: 28
							thoughts: 249
						

Thoughts:
**My Analysis of Default Group Removal in ConfigFS**

Okay, so `configfs_remove_default_groups` seems straightforward enough. It iterates through `default_groups`, removes them from the list, and then calls `config_item_put`. Standard refcount management. But, hang on... didn't I see something similar elsewhere? Ah, yes, `uvcg_config_remove_children` also removes things, but it does it recursively. Hmm, does `configfs_remove_default_groups` handle recursion? No, it doesn't.

Now, I remember `f_midi2` has this hierarchical structure of default groups: we're dealing with `opts->func_inst.group`, `ep_opts->group`, and `block_opts->group`. If I call `configfs_remove_default_groups` on `&opts->func_inst.group`, that's going to drop the refcount of `ep_opts->group`. That triggers `f_midi2_ep_opts_release`, I know this because that's where I setup the release code.

The issue is that if I then call `configfs_remove_default_groups` on `&ep_opts->group` *within* `f_midi2_ep_opts_release`, it would drop the refcount of `block_opts->group`. This will then trigger `f_midi2_block_opts_release`. It's a cascading effect down the hierarchy.

Let me just double-check the logic in `f_midi2_ep_opts_release` again to be sure I'm not missing anything. Gotta make sure this refcounting and release dance is clean.



115/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:f_midi2_ep_opts_release]

Results:
map[SourceCode:2472:	static void f_midi2_ep_opts_release(struct config_item *item)
2473:	{
2474:		struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
2475:	
2476:		kfree(opts->info.ep_name);
2477:		kfree(opts->info.product_id);
2478:		kfree(opts);
2479:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

116/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 65689
							output: 30
							thoughts: 323
						

Thoughts:
**Debugging a Potential Leak in MIDI2 Functionality**

Okay, so I'm trying to track down this memory leak, and I'm thinking about where we're releasing resources in the MIDI2 code. My initial thought is, if I add `configfs_remove_default_groups(to_config_group(item))` to both `f_midi2_ep_opts_release` and `f_midi2_opts_release`, would that plug the hole? It seems like the obvious place to start since we're dealing with configfs items and groups here.

Hold on, though. Looking closer at `f_midi2_opts_release`, I see that it's called when `opts->func_inst.group` is released. That's good, that's what I want. Now, looking at `f_midi2_ep_opts_release`, I see some `kfree`s to handle individual properties being freed. The `configfs_remove_default_groups` should probably be here too. Okay, so that should address the configfs group removal.

Wait a second...is `configfs_remove_default_groups` actually exported? I need to check the headers to make sure I can even *call* that function. That's a key detail I need to confirm before I even consider making the change. If it's not exported, then I need to figure out what the correct function call is to remove those configfs groups.



117/2 2026/07/30 14:12 tool grepper
0m Error:
no matches

Args:
map[Expression:EXPORT_SYMBOL_GPL\(configfs_remove_default_groups\)]

Results:
map[Output:]

118/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 66371
							output: 26
							thoughts: 20
						

Thoughts:
Okay, here's my summary, taking the role of the expert:

**Investigating `configfs_remove_default_groups` and its Symbol Export**

Right, let's dive into this. The task at hand is to analyze the `EXPORT_SYMBOL` status of the function `configfs_remove_default_groups`. I need to understand if it's visible, accessible, and potentially usable (or abused) outside of its intended scope. My immediate thought is, "Is this exposed intentionally, or is it a potential internal leakage?" That distinction is crucial. It tells us about the design choices and the dependency relationships within the configfs subsystem. Knowing if it's exported also directly impacts security considerations. If it is exported then it is available for other drivers or modules to use, and if it is not exported, it is not.



119/2 2026/07/30 14:12 tool grepper
0m Args:
map[Expression:EXPORT_SYMBOL.*configfs_remove_default_groups]

Results:
map[Output:fs/configfs/dir.c=748=void configfs_remove_default_groups(struct config_group *group)
--
fs/configfs/dir.c-756-}
fs/configfs/dir.c:757:EXPORT_SYMBOL(configfs_remove_default_groups);
fs/configfs/dir.c-758-
]

120/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 66694
							output: 25
							thoughts: 3113
						

Thoughts:
**Analysis of `f_midi2` Device Option Release and Resource Management**

Okay, so I've been reviewing the logic around the creation, release, and possible leaks of `ep_opts` and `block_opts` structures within the `f_midi2` device driver, especially in the context of configfs. My initial thought process is to trace where these objects are created and how their lifecycles are managed, looking for potential use-after-free or double-free scenarios.

First, I confirm the initial creation of default endpoint and block options using `f_midi2_ep_opts_create` and `f_midi2_block_opts_create`. I see that on failure, the appropriate frees are called. I then note the use of `config_group_init_type_name` and the creation of the default groups. I also check that the refcounts are correctly managed with respect to `kfree` and dynamic allocation. If `f_midi2_block_opts_create` fails, it correctly frees `ep_opts` and `opts`. The crucial thing here is to ensure the relationships between the configfs groups and the underlying data structures. `config_group_init_type_name` creates a reference to these.

I then focus on the scenario where a user creates and subsequently removes a configfs directory. If the allocation function `f_midi2_alloc_inst` fails after the structures are created in configfs, the release functions (`f_midi2_opts_release`, `f_midi2_ep_opts_release`, `f_midi2_block_opts_release`) become relevant.

I need to confirm the use of `configfs_remove_default_groups` to ensure all children are released. I think that adding it to `f_midi2_opts_release` is necessary because `opts` is the root group. The crucial point here is whether `f_midi2_ep_opts_release` and `f_midi2_block_opts_release` are doing the right thing in terms of freeing resources and avoiding double-frees.

My next line of thinking involved the dynamic creation of endpoints and blocks via `mkdir`. I determined the corresponding `make_group` and `drop_item` callbacks (`f_midi2_opts_ep_make`, `f_midi2_opts_ep_drop`, `f_midi2_opts_block_make`, and `f_midi2_opts_block_drop`). I then followed the code flow in these drop functions.

I realize that dynamically created `ep_opts` and `block_opts` do *not* have default groups, and are removed via `rmdir` directly by the user.

Then, I focused on the scenario of `f_midi2_opts_release` versus `usb_put_function_instance`, ensuring I account for both paths. I see that there is a different release path for dynamically created instances through `usb_put_function_instance`. I confirm that `usb_put_function_instance` calls `f_midi2_free_inst` and that this path bypasses `config_item_put` and `f_midi2_opts_release` completely. This is the crucial point to make sure there are no leaks.

So in summary, the only release path goes through `usb_put_function_instance`, which then leads to `f_midi2_free_inst`. This seems to avoid the need to handle the release of default groups separately. This needs to be carefully documented.



121/2 2026/07/30 14:12 tool codesearch-definition-source
0m Args:
map[Name:usb_put_function_instance]

Results:
map[SourceCode:  69:	void usb_put_function_instance(struct usb_function_instance *fi)
  70:	{
  71:		struct module *mod;
  72:	
  73:		if (!fi)
  74:			return;
  75:	
  76:		mod = fi->fd->mod;
  77:		fi->free_func_inst(fi);
  78:		module_put(mod);
  79:	}
 SourceFile:drivers/usb/gadget/functions.c]

122/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 70743
							output: 22
							thoughts: 2036
						

Thoughts:
**Analyzing USB Function Instance Lifecycle and Potential Memory Leaks**

Okay, so I'm thinking through how `usb_put_function_instance` interacts with freeing function instances, specifically looking at how we prevent memory leaks. I've realized that the standard call chain `usb_put_function_instance` -> `fi->free_func_inst(fi)` is central, but the details are subtle. The critical thing to consider is whether we are dealing with a configfs-managed instance, or one handled directly.

My initial thought was, if `f_midi2_free_inst` doesn't free `ep_opts` and `block_opts`, we'll have a leak if `usb_put_function_instance` is called directly. However, if `config_group_init_type_name` initialized `fi->group`, it starts with a refcount of 1. If the `function_make` succeeds, it returns `&fi->group` and configfs takes over the refcount of `fi->group`. When the configfs directory is removed, `function_drop` is called, and `config_item_put` drops the refcount of `fi->group.cg_item`. When it reaches 0, `f_midi2_opts_release` is called, and then `usb_put_function_instance` is called again, triggering the intended `f_midi2_free_inst` call.

So, `f_midi2_free_inst` is ALWAYS called, regardless of the path. However, `f_midi2_opts_release` is ONLY called if configfs took over. Here's the key: if `usb_put_function_instance` is called directly (for example, in an error path in `function_make`, or by legacy gadget drivers) `f_midi2_opts_release` is NEVER called! Therefore if we put `configfs_remove_default_groups` in `f_midi2_opts_release`, it would be skipped in the direct path and the default groups will be leaked.

The conclusion is that we MUST free `ep_opts` and `block_opts` in `f_midi2_free_inst`. However, if configfs is still holding references to them, we might be in trouble. But because `f_midi2_free_inst` is called when the refcount of `fi` has reached 0, and if the path was through configfs, `config_item_put` had reached 0, so configfs is no longer holding a reference. So, the question remains about default groups. If we call `configfs_remove_default_groups(&opts->func_inst.group)` in `f_midi2_free_inst`, this would drop the refcount of the default groups, and then we could free. Following this logic we would then add `configfs_remove_default_groups(&opts->group)` in the `f_midi2_ep_opts_release` (and similar release functions).

I then considered how UVC handles this. It looks like it calls `uvcg_config_remove_children` from `uvc_func_item_release` NOT from `uvc_free_inst`. This removes children from the default groups. `uvc_alloc_inst` calls `uvcg_attach_configfs` to allocate the default groups and add them to `default_groups`. In the direct `usb_put_function_instance` case, `uvc_free_inst` is called which *only* frees `opts` not the default groups! This means the default groups are LEAKED!

So, `usb_put_function_instance` can be called directly in error paths (like if `config_item_set_name` fails) which means in the current uvc implementation, the default groups *are* leaked. Note, because `uvc` can be used by legacy drivers, the problem is more general. This is a very clear example of the problem, and a critical bug. It suggests that my `f_midi2` design, with the call to `configfs_remove_default_groups` in `f_midi2_free_inst` is correct.



123/2 2026/07/30 14:12 tool codesearch-definition-source
0m Error:
requested entity does not exist

Args:
map[Name:webcam_bind]

Results:
map[SourceCode: SourceFile:]

124/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 73731
							output: 21
							thoughts: 30
						

Thoughts:
Here's my thought process, as if I were considering this search:

**Diving into the Webcam Driver**

Okay, so I need to find where `usb_get_function_instance` is used within the legacy webcam driver. My initial instinct is to target `drivers/usb/gadget/legacy/webcam.c`. That seems like the most logical place to start, given the function name and the context of USB gadget drivers. I'm expecting this function deals with obtaining a function instance, which, in a gadget context, probably relates to how the webcam driver exposes itself as a USB function. Let's see what we can find. I'll get to it.



125/2 2026/07/30 14:12 tool grepper
0m Args:
map[Expression:usb_get_function_instance]

Results:
map[Output:Documentation/usb/gadget_configfs.rst=369=The concepts described above translate to USB gadgets like this:
--
Documentation/usb/gadget_configfs.rst-395-5. Function's code is written in such a way that it uses
Documentation/usb/gadget_configfs.rst:396:   usb_get_function_instance(), which, in turn, calls request_module.  So,
Documentation/usb/gadget_configfs.rst-397-   provided that modprobe works, modules for particular functions are loaded
--
drivers/usb/gadget/configfs.c=601=static struct config_group *function_make(
--
drivers/usb/gadget/configfs.c-625-
drivers/usb/gadget/configfs.c:626:	fi = usb_get_function_instance(func_name);
drivers/usb/gadget/configfs.c-627-	if (IS_ERR(fi))
--
drivers/usb/gadget/functions.c=12=static struct usb_function_instance *try_get_usb_function_instance(const char *name)
--
drivers/usb/gadget/functions.c-38-
drivers/usb/gadget/functions.c:39:struct usb_function_instance *usb_get_function_instance(const char *name)
drivers/usb/gadget/functions.c-40-{
--
drivers/usb/gadget/functions.c-54-}
drivers/usb/gadget/functions.c:55:EXPORT_SYMBOL_GPL(usb_get_function_instance);
drivers/usb/gadget/functions.c-56-
--
drivers/usb/gadget/legacy/acm_ms.c=152=static int acm_ms_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/acm_ms.c-158-
drivers/usb/gadget/legacy/acm_ms.c:159:	f_acm_inst = usb_get_function_instance("acm");
drivers/usb/gadget/legacy/acm_ms.c-160-	if (IS_ERR(f_acm_inst))
--
drivers/usb/gadget/legacy/acm_ms.c-162-
drivers/usb/gadget/legacy/acm_ms.c:163:	fi_msg = usb_get_function_instance("mass_storage");
drivers/usb/gadget/legacy/acm_ms.c-164-	if (IS_ERR(fi_msg)) {
--
drivers/usb/gadget/legacy/audio.c=253=static int audio_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/audio.c-268-#ifndef CONFIG_GADGET_UAC1
drivers/usb/gadget/legacy/audio.c:269:	fi_uac2 = usb_get_function_instance("uac2");
drivers/usb/gadget/legacy/audio.c-270-	if (IS_ERR(fi_uac2))
--
drivers/usb/gadget/legacy/audio.c-273-#ifndef CONFIG_GADGET_UAC1_LEGACY
drivers/usb/gadget/legacy/audio.c:274:	fi_uac1 = usb_get_function_instance("uac1");
drivers/usb/gadget/legacy/audio.c-275-#else
drivers/usb/gadget/legacy/audio.c:276:	fi_uac1 = usb_get_function_instance("uac1_legacy");
drivers/usb/gadget/legacy/audio.c-277-#endif
--
drivers/usb/gadget/legacy/cdc2.c=138=static int cdc_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/cdc2.c-149-
drivers/usb/gadget/legacy/cdc2.c:150:	fi_ecm = usb_get_function_instance("ecm");
drivers/usb/gadget/legacy/cdc2.c-151-	if (IS_ERR(fi_ecm))
--
drivers/usb/gadget/legacy/cdc2.c-161-
drivers/usb/gadget/legacy/cdc2.c:162:	fi_serial = usb_get_function_instance("acm");
drivers/usb/gadget/legacy/cdc2.c-163-	if (IS_ERR(fi_serial)) {
--
drivers/usb/gadget/legacy/ether.c=304=static int eth_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/ether.c-315-		/* EEM */
drivers/usb/gadget/legacy/ether.c:316:		fi_eem = usb_get_function_instance("eem");
drivers/usb/gadget/legacy/ether.c-317-		if (IS_ERR(fi_eem))
--
drivers/usb/gadget/legacy/ether.c-329-
drivers/usb/gadget/legacy/ether.c:330:		fi_ecm = usb_get_function_instance("ecm");
drivers/usb/gadget/legacy/ether.c-331-		if (IS_ERR(fi_ecm))
--
drivers/usb/gadget/legacy/ether.c-341-
drivers/usb/gadget/legacy/ether.c:342:		fi_geth = usb_get_function_instance("geth");
drivers/usb/gadget/legacy/ether.c-343-		if (IS_ERR(fi_geth))
--
drivers/usb/gadget/legacy/ether.c-378-
drivers/usb/gadget/legacy/ether.c:379:		fi_rndis = usb_get_function_instance("rndis");
drivers/usb/gadget/legacy/ether.c-380-		if (IS_ERR(fi_rndis)) {
--
drivers/usb/gadget/legacy/g_ffs.c=177=static int __init gfs_init(void)
--
drivers/usb/gadget/legacy/g_ffs.c-205-	for (i = 0; i < func_num; i++) {
drivers/usb/gadget/legacy/g_ffs.c:206:		fi_ffs[i] = usb_get_function_instance("ffs");
drivers/usb/gadget/legacy/g_ffs.c-207-		if (IS_ERR(fi_ffs[i])) {
--
drivers/usb/gadget/legacy/g_ffs.c=308=static int gfs_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/g_ffs.c-320-
drivers/usb/gadget/legacy/g_ffs.c:321:		fi_ecm = usb_get_function_instance("ecm");
drivers/usb/gadget/legacy/g_ffs.c-322-		if (IS_ERR(fi_ecm))
--
drivers/usb/gadget/legacy/g_ffs.c-328-
drivers/usb/gadget/legacy/g_ffs.c:329:		fi_geth = usb_get_function_instance("geth");
drivers/usb/gadget/legacy/g_ffs.c-330-		if (IS_ERR(fi_geth))
--
drivers/usb/gadget/legacy/g_ffs.c-339-	{
drivers/usb/gadget/legacy/g_ffs.c:340:		fi_rndis = usb_get_function_instance("rndis");
drivers/usb/gadget/legacy/g_ffs.c-341-		if (IS_ERR(fi_rndis)) {
--
drivers/usb/gadget/legacy/gmidi.c=142=static int midi_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/gmidi.c-146-
drivers/usb/gadget/legacy/gmidi.c:147:	fi_midi = usb_get_function_instance("midi");
drivers/usb/gadget/legacy/gmidi.c-148-	if (IS_ERR(fi_midi))
--
drivers/usb/gadget/legacy/hid.c=133=static int hid_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/hid.c-144-	list_for_each_entry(iter_n, &hidg_func_list, node) {
drivers/usb/gadget/legacy/hid.c:145:		iter_n->fi = usb_get_function_instance("hid");
drivers/usb/gadget/legacy/hid.c-146-		if (IS_ERR(iter_n->fi)) {
--
drivers/usb/gadget/legacy/mass_storage.c=139=static int msg_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/mass_storage.c-144-
drivers/usb/gadget/legacy/mass_storage.c:145:	fi_msg = usb_get_function_instance("mass_storage");
drivers/usb/gadget/legacy/mass_storage.c-146-	if (IS_ERR(fi_msg))
--
drivers/usb/gadget/legacy/multi.c=294=static int multi_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/multi.c-313-#ifdef CONFIG_USB_G_MULTI_CDC
drivers/usb/gadget/legacy/multi.c:314:	fi_ecm = usb_get_function_instance("ecm");
drivers/usb/gadget/legacy/multi.c-315-	if (IS_ERR(fi_ecm))
--
drivers/usb/gadget/legacy/multi.c-327-#ifdef USB_ETH_RNDIS
drivers/usb/gadget/legacy/multi.c:328:	fi_rndis = usb_get_function_instance("rndis");
drivers/usb/gadget/legacy/multi.c-329-	if (IS_ERR(fi_rndis)) {
--
drivers/usb/gadget/legacy/multi.c-359-	/* set up serial link layer */
drivers/usb/gadget/legacy/multi.c:360:	fi_acm = usb_get_function_instance("acm");
drivers/usb/gadget/legacy/multi.c-361-	if (IS_ERR(fi_acm)) {
--
drivers/usb/gadget/legacy/multi.c-366-	/* set up mass storage function */
drivers/usb/gadget/legacy/multi.c:367:	fi_msg = usb_get_function_instance("mass_storage");
drivers/usb/gadget/legacy/multi.c-368-	if (IS_ERR(fi_msg)) {
--
drivers/usb/gadget/legacy/ncm.c=127=static int gncm_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/ncm.c-132-
drivers/usb/gadget/legacy/ncm.c:133:	f_ncm_inst = usb_get_function_instance("ncm");
drivers/usb/gadget/legacy/ncm.c-134-	if (IS_ERR(f_ncm_inst))
--
drivers/usb/gadget/legacy/nokia.c=267=static int nokia_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/nokia.c-287-
drivers/usb/gadget/legacy/nokia.c:288:	fi_phonet = usb_get_function_instance("phonet");
drivers/usb/gadget/legacy/nokia.c-289-	if (IS_ERR(fi_phonet))
--
drivers/usb/gadget/legacy/nokia.c-291-
drivers/usb/gadget/legacy/nokia.c:292:	fi_obex1 = usb_get_function_instance("obex");
drivers/usb/gadget/legacy/nokia.c-293-	if (IS_ERR(fi_obex1))
--
drivers/usb/gadget/legacy/nokia.c-295-
drivers/usb/gadget/legacy/nokia.c:296:	fi_obex2 = usb_get_function_instance("obex");
drivers/usb/gadget/legacy/nokia.c-297-	if (IS_ERR(fi_obex2))
--
drivers/usb/gadget/legacy/nokia.c-299-
drivers/usb/gadget/legacy/nokia.c:300:	fi_acm = usb_get_function_instance("acm");
drivers/usb/gadget/legacy/nokia.c-301-	if (IS_ERR(fi_acm)) {
--
drivers/usb/gadget/legacy/nokia.c-305-
drivers/usb/gadget/legacy/nokia.c:306:	fi_ecm = usb_get_function_instance("ecm");
drivers/usb/gadget/legacy/nokia.c-307-	if (IS_ERR(fi_ecm)) {
--
drivers/usb/gadget/legacy/nokia.c-311-
drivers/usb/gadget/legacy/nokia.c:312:	fi_msg = usb_get_function_instance("mass_storage");
drivers/usb/gadget/legacy/nokia.c-313-	if (IS_ERR(fi_msg)) {
--
drivers/usb/gadget/legacy/printer.c=139=static int printer_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/printer.c-143-
drivers/usb/gadget/legacy/printer.c:144:	fi_printer = usb_get_function_instance("printer");
drivers/usb/gadget/legacy/printer.c-145-	if (IS_ERR(fi_printer))
--
drivers/usb/gadget/legacy/serial.c=143=static int serial_register_ports(struct usb_composite_dev *cdev,
--
drivers/usb/gadget/legacy/serial.c-154-
drivers/usb/gadget/legacy/serial.c:155:		fi_serial[i] = usb_get_function_instance(f_name);
drivers/usb/gadget/legacy/serial.c-156-		if (IS_ERR(fi_serial[i])) {
--
drivers/usb/gadget/legacy/tcm_usb_gadget.c=140=static int __init usb_target_gadget_init(void)
--
drivers/usb/gadget/legacy/tcm_usb_gadget.c-143-
drivers/usb/gadget/legacy/tcm_usb_gadget.c:144:	fi_tcm = usb_get_function_instance("tcm");
drivers/usb/gadget/legacy/tcm_usb_gadget.c-145-	if (IS_ERR(fi_tcm))
--
drivers/usb/gadget/legacy/webcam.c=525=webcam_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/webcam.c-529-
drivers/usb/gadget/legacy/webcam.c:530:	fi_uvc = usb_get_function_instance("uvc");
drivers/usb/gadget/legacy/webcam.c-531-	if (IS_ERR(fi_uvc))
--
drivers/usb/gadget/legacy/zero.c=274=static int zero_bind(struct usb_composite_dev *cdev)
--
drivers/usb/gadget/legacy/zero.c-293-
drivers/usb/gadget/legacy/zero.c:294:	func_inst_ss = usb_get_function_instance("SourceSink");
drivers/usb/gadget/legacy/zero.c-295-	if (IS_ERR(func_inst_ss))
--
drivers/usb/gadget/legacy/zero.c-313-
drivers/usb/gadget/legacy/zero.c:314:	func_inst_lb = usb_get_function_instance("Loopback");
drivers/usb/gadget/legacy/zero.c-315-	if (IS_ERR(func_inst_lb)) {
--
include/linux/usb/composite.h=591=void usb_put_function(struct usb_function *f);
include/linux/usb/composite.h:592:struct usb_function_instance *usb_get_function_instance(const char *name);
include/linux/usb/composite.h-593-struct usb_function *usb_get_function(struct usb_function_instance *fi);
]

126/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 78262
							output: 22
							thoughts: 2500
						

Thoughts:
**Analysis of Default Group Management in USB Gadget Functions**

Okay, so I've been digging into the USB gadget function (`g_webcam.c` in particular) and I've identified a potential resource leak in how default groups are handled, specifically in the `uvc` module and, importantly, how this issue applies to `f_midi2`.

My initial thought process was: I saw that `g_webcam.c` uses `usb_get_function_instance("uvc")`. If a later `webcam_bind` fails, `usb_put_function_instance(fi_uvc)` is called which, in turn, calls `uvc_free_inst`. `uvc_free_inst` frees `opts`, but I noticed it *doesn't* free the default groups. I immediately checked the code again, and, confirmed my initial read. `uvc_free_inst` does NOT drop the refcount on those default groups. This is a potential leak.

The key observation is that if `uvc_free_inst` doesn't clean up the default groups, and `usb_put_function_instance` is called directly, those groups are leaked. However, `uvc_func_item_release` *should* call `uvcg_config_remove_children`, which would drop the refcount. *But*, if `usb_put_function_instance` is called directly, that release function is *never* called, because the configfs item was never exposed to userspace or its refcount was never managed by configfs. The initial refcount of the config group, which is initialized by `config_group_init_type_name` to 1, remains untouched! Thus, the default groups are leaked.

This is a known issue.

Now, let's turn to `f_midi2`. Can we fix the leak in `f_midi2` by calling `configfs_remove_default_groups` in `f_midi2_free_inst`? If `f_midi2_opts_release` also calls `configfs_remove_default_groups`, what happens? If it is safe to call the function in both release paths, then the code could be made more resilient to use. If `f_midi2_opts_release` calls it, the default group list is emptied, so calling it in `f_midi2_free_inst` is a no-op, meaning it is safe.

Let's walk through the logic. If we *only* call `configfs_remove_default_groups` in `f_midi2_free_inst` and not `f_midi2_opts_release`, what happens? When `opts->func_inst.group` is released, `f_midi2_opts_release` is called, which in turn calls `usb_put_function_instance`, which then calls `f_midi2_free_inst`.  In `f_midi2_free_inst`, we'll call `configfs_remove_default_groups(&opts->func_inst.group)`. This will drop the refcount of `ep_opts->group`. Next, `f_midi2_ep_opts_release` is called. If that function calls `configfs_remove_default_groups(to_config_group(item))`, the refcount of `block_opts->group` is dropped.  Then, `f_midi2_block_opts_release` is called (which frees `block_opts`), then `f_midi2_ep_opts_release` (which frees `ep_opts`), then `f_midi2_free_inst` (which frees `opts`). This all works perfectly!

I looked at the failure paths. What if `f_midi2_alloc_inst` fails after `f_midi2_block_opts_create`? It fails by freeing `ep_opts` and `opts`. Since `config_group_init_type_name` hasn't been called on `ep_opts->group` or `opts->func_inst.group`, those pointers are just raw memory, and `kfree` is the correct action. If `f_midi2_ep_opts_create` also never calls `config_group_init_type_name`, we are fine.

What if `f_midi2_alloc_inst` succeeds, but `usb_put_function_instance` is called directly? `f_midi2_free_inst` is called. It calls `configfs_remove_default_groups(&opts->func_inst.group)`. `config_group_init_type_name` initializes `default_groups` list, and `configfs_add_


127/2 2026/07/30 14:12 tool grepper
0m Args:
map[Expression:configfs_remove_default_groups]

Results:
map[Output:drivers/infiniband/core/cma_configfs.c=318=static void drop_cma_dev(struct config_group *cgroup, struct config_item *item)
--
drivers/infiniband/core/cma_configfs.c-324-
drivers/infiniband/core/cma_configfs.c:325:	configfs_remove_default_groups(&cma_dev_group->ports_group);
drivers/infiniband/core/cma_configfs.c:326:	configfs_remove_default_groups(&cma_dev_group->device_group);
drivers/infiniband/core/cma_configfs.c-327-	config_item_put(item);
--
drivers/target/target_core_configfs.c=267=static void target_core_deregister_fabric(
--
drivers/target/target_core_configfs.c-283-
drivers/target/target_core_configfs.c:284:	configfs_remove_default_groups(&tf->tf_group);
drivers/target/target_core_configfs.c-285-	config_item_put(item);
--
drivers/target/target_core_configfs.c=3502=static void target_core_drop_subdev(
--
drivers/target/target_core_configfs.c-3514-
drivers/target/target_core_configfs.c:3515:	configfs_remove_default_groups(&dev->dev_stat_grps.stat_group);
drivers/target/target_core_configfs.c:3516:	configfs_remove_default_groups(&dev->t10_alua.alua_tg_pt_gps_group);
drivers/target/target_core_configfs.c-3517-
--
drivers/target/target_core_configfs.c-3523-
drivers/target/target_core_configfs.c:3524:	configfs_remove_default_groups(dev_cg);
drivers/target/target_core_configfs.c-3525-
--
drivers/target/target_core_configfs.c=3843=static void __exit target_core_exit_configfs(void)
drivers/target/target_core_configfs.c-3844-{
drivers/target/target_core_configfs.c:3845:	configfs_remove_default_groups(&alua_lu_gps_group);
drivers/target/target_core_configfs.c:3846:	configfs_remove_default_groups(&alua_group);
drivers/target/target_core_configfs.c:3847:	configfs_remove_default_groups(&target_core_hbagroup);
drivers/target/target_core_configfs.c-3848-
--
drivers/target/target_core_fabric_configfs.c=326=static void target_fabric_drop_mappedlun(
--
drivers/target/target_core_fabric_configfs.c-332-
drivers/target/target_core_fabric_configfs.c:333:	configfs_remove_default_groups(&lacl->ml_stat_grps.stat_group);
drivers/target/target_core_fabric_configfs.c:334:	configfs_remove_default_groups(&lacl->se_lun_group);
drivers/target/target_core_fabric_configfs.c-335-
--
drivers/target/target_core_fabric_configfs.c=339=static void target_fabric_nacl_base_release(struct config_item *item)
--
drivers/target/target_core_fabric_configfs.c-343-
drivers/target/target_core_fabric_configfs.c:344:	configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
drivers/target/target_core_fabric_configfs.c-345-	core_tpg_del_initiator_node_acl(se_nacl);
--
drivers/target/target_core_fabric_configfs.c=373=static struct config_group *target_fabric_make_nodeacl(
--
drivers/target/target_core_fabric_configfs.c-411-		if (ret) {
drivers/target/target_core_fabric_configfs.c:412:			configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
drivers/target/target_core_fabric_configfs.c-413-			core_tpg_del_initiator_node_acl(se_nacl);
--
drivers/target/target_core_fabric_configfs.c=421=static void target_fabric_drop_nodeacl(
--
drivers/target/target_core_fabric_configfs.c-427-
drivers/target/target_core_fabric_configfs.c:428:	configfs_remove_default_groups(&se_nacl->acl_group);
drivers/target/target_core_fabric_configfs.c-429-
--
drivers/target/target_core_fabric_configfs.c=777=static void target_fabric_drop_lun(
--
drivers/target/target_core_fabric_configfs.c-783-
drivers/target/target_core_fabric_configfs.c:784:	configfs_remove_default_groups(&lun->port_stat_grps.stat_group);
drivers/target/target_core_fabric_configfs.c:785:	configfs_remove_default_groups(&lun->lun_group);
drivers/target/target_core_fabric_configfs.c-786-
--
drivers/target/target_core_fabric_configfs.c=979=static void target_fabric_drop_tpg(
--
drivers/target/target_core_fabric_configfs.c-985-
drivers/target/target_core_fabric_configfs.c:986:	configfs_remove_default_groups(&se_tpg->tpg_group);
drivers/target/target_core_fabric_configfs.c-987-	config_item_put(item);
--
drivers/target/target_core_fabric_configfs.c=990=static void target_fabric_release_wwn(struct config_item *item)
--
drivers/target/target_core_fabric_configfs.c-995-
drivers/target/target_core_fabric_configfs.c:996:	configfs_remove_default_groups(&wwn->fabric_stat_group);
drivers/target/target_core_fabric_configfs.c:997:	configfs_remove_default_groups(&wwn->param_group);
drivers/target/target_core_fabric_configfs.c-998-	tf->tf_ops->fabric_drop_wwn(wwn);
--
drivers/target/target_core_fabric_configfs.c=1160=static void target_fabric_drop_wwn(
--
drivers/target/target_core_fabric_configfs.c-1166-
drivers/target/target_core_fabric_configfs.c:1167:	configfs_remove_default_groups(&wwn->wwn_group);
drivers/target/target_core_fabric_configfs.c-1168-	config_item_put(item);
--
fs/configfs/dir.c=734=static int populate_groups(struct config_group *group,
--
fs/configfs/dir.c-747-
fs/configfs/dir.c:748:void configfs_remove_default_groups(struct config_group *group)
fs/configfs/dir.c-749-{
--
fs/configfs/dir.c-756-}
fs/configfs/dir.c:757:EXPORT_SYMBOL(configfs_remove_default_groups);
fs/configfs/dir.c-758-
--
fs/dlm/config.c=457=static void drop_cluster(struct config_group *g, struct config_item *i)
--
fs/dlm/config.c-460-
fs/dlm/config.c:461:	configfs_remove_default_groups(&cl->group);
fs/dlm/config.c-462-
--
fs/dlm/config.c=507=static void drop_space(struct config_group *g, struct config_item *i)
--
fs/dlm/config.c-512-
fs/dlm/config.c:513:	configfs_remove_default_groups(&sp->group);
fs/dlm/config.c-514-	config_item_put(i);
--
fs/ocfs2/cluster/nodemanager.c=733=static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item)
--
fs/ocfs2/cluster/nodemanager.c-739-
fs/ocfs2/cluster/nodemanager.c:740:	configfs_remove_default_groups(&cluster->cl_group);
fs/ocfs2/cluster/nodemanager.c-741-	config_item_put(item);
--
include/linux/configfs.h=245=void configfs_unregister_group(struct config_group *group);
include/linux/configfs.h-246-
include/linux/configfs.h:247:void configfs_remove_default_groups(struct config_group *group);
include/linux/configfs.h-248-
]

128/2 2026/07/30 14:12 llm debugger
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 84251
							output: 744
							thoughts: 2285
						

Thoughts:
**Analysis of a ConfigFS Memory Leak in f_midi2**

Okay, so I've been digging into this memory leak reported in the `f_midi2` gadget driver, and I think I've got a handle on it. First, I confirmed that the issue is indeed rooted in how `configfs` handles default groups. I know from experience that other modules, like those in `drivers/infiniband/core`, `drivers/target`, `fs/dlm`, and `fs/ocfs2`, also use `configfs` for this purpose and call `configfs_remove_default_groups` to clean things up. This gives me a good point of reference.

The leak stems from `f_midi2_alloc_inst`, which creates and adds `ep.0` and `block.0` configfs groups as default groups under the function instance. These groups, and the associated data structures (`f_midi2_ep_opts` and `f_midi2_block_opts`) are then never properly released when the configfs directory is removed or the function instance is released. The hex dump from the crash report confirms that the leaked objects are the `ep_opts` and `block_opts` structures. The names `ep.0` and `block.0` are the configfs group names stored in `ci_namebuf`, so those names being present helps me confirm this is indeed the correct area to examine.

I realized the critical oversight is that `configfs` *doesn't* automatically drop the refcounts of these default groups when the parent is removed. We need to explicitly handle it within the driver. So, the fix should involve calling `configfs_remove_default_groups` at the appropriate points. Specifically:

*   In `f_midi2_free_inst`, before freeing the `f_midi2_opts` structure, I need to add `configfs_remove_default_groups(&opts->func_inst.group)`. This should trigger the release of `ep.0` and `block.0`.
*   And in `f_midi2_ep_opts_release`, I need to add `configfs_remove_default_groups(to_config_group(item))` before `kfree(opts)`.

I quickly double-checked the flow. Since `f_midi2_opts_release` calls `usb_put_function_instance`, which then calls `f_midi2_free_inst`, I only need to add the call to `configfs_remove_default_groups` in `f_midi2_free_inst`.

I reviewed the code, and I'm confident that this covers all the default groups added in `f_midi2_alloc_inst`. There are no others. I also made sure dynamically allocated strings like `info.iface_name`, `info.ep_name`, `info.product_id` and the `info.name` are freed in the appropriate release functions. So, no other leaks there.

I've also looked at `f_uvc.c` as a comparison, as it's been the subject of a similar discussion, but `f_uvc.c` does call `uvcg_config_remove_children` in `uvc_func_item_release` after all. And `f_midi2` doesn't even have an equivalent call to handle cases of direct function instance release!

Therefore, I'm confident that these additions will resolve the memory leak by ensuring the refcounts of the default groups are properly dropped, triggering their release functions and freeing the associated structures.



129/1 2026/07/30 14:12 agent history-explorer
28m Model:
best-expensive

Instruction:
You are an experienced Linux kernel developer researching prior art for fixing a kernel bug.
You are given a bug explanation. This explanation details the root cause of the bug resulting
from debugging, but does not provide the final fix strategy. Your goal is to explore how
similar bugs were fixed in the past in the same subsystem or files.

CRITICAL: Do NOT attempt to debug the issue further or write a patch for it yourself.
Your ONLY objective is to research and provide the necessary historical context.

Use the git-log tool with the Since parameter set to "3 years" to focus on recent history.
Search for commits that address issues with similar root causes (e.g. similar missing locks,
incorrect refcounting, or similar error path bugs) in the affected files.

Your final reply must summarize your findings: what idioms, locking rules, or common patterns
should be followed when writing a fix for this bug based on how previous similar bugs were addressed.
If you find no relevant past fixes, clearly state that.

Don't make assumptions about the kernel source code (it may be different from what you assume it is).
Extensively use the provided code access tools (codesearch-*, git-*, grepper, etc)
to examine the actual source code, and confirm any assumptions.

Prefer calling several tools at the same time to save round-trips.

Prompt:
The crash is:

2026/07/30 13:30:35 executed programs: 5
BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504 [inline]
    f_midi2_alloc_inst+0x80/0x2c0 drivers/usb/gadget/function/f_midi2.c:2666
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342 [inline]
    f_midi2_alloc_inst+0x16a/0x2c0 drivers/usb/gadget/function/f_midi2.c:2673
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF


The explanation of the root cause of the bug is:

The root cause of this memory leak is that the driver fails to drop the reference counts of its default configfs groups when the parent group is destroyed.

When a USB function instance for `midi2` is allocated via `f_midi2_alloc_inst()`, it dynamically allocates `ep_opts` and `block_opts` structures using `kzalloc_obj()`. These structures are then initialized as configfs groups and added as default groups to their respective parents:
- `ep.0` is added as a default group to the function instance group (`opts->func_inst.group`).
- `block.0` is added as a default group to the endpoint group (`ep_opts->group`).

When the user removes the configfs directory for the function instance (via `rmdir`), configfs removes the dentries for the default groups but **does not** automatically drop their reference counts. The responsibility of dropping the refcounts of default groups lies with the driver, typically by calling `configfs_remove_default_groups()` when the parent group is released.

However, `f_midi2_free_inst()` (which is called when the function instance's refcount reaches 0) only frees the `f_midi2_opts` structure and does not clean up its default groups. Similarly, `f_midi2_ep_opts_release()` does not clean up its default groups. As a result, the `ep_opts` and `block_opts` structures are leaked.

### How to fix it

To fix the leak, you need to explicitly remove the default groups and drop their reference counts before freeing the parent structures. This can be done by calling `configfs_remove_default_groups()` in the respective release functions.

1. In `f_midi2_free_inst()`, drop the default groups of the function instance (this will drop the refcount of `ep.0` and trigger `f_midi2_ep_opts_release`):
```c
static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group); /* ADD THIS */
	kfree(opts->info.iface_name);
	kfree(opts);
}
```

2. In `f_midi2_ep_opts_release()`, drop the default groups of the endpoint (this will drop the refcount of `block.0` and trigger `f_midi2_block_opts_release`):
```c
static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item)); /* ADD THIS */
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
}
```

With these changes, the hierarchy of default groups will be properly unrolled and freed when the function instance is destroyed, whether it's through configfs `rmdir` or an error path that directly calls `usb_put_function_instance()`.

Reply:
Based on the historical research of similar bugs in the kernel, here is a summary of the findings and the recommended patterns for fixing this issue.

### Findings

The root cause of the bug is that dynamically allocated configfs default groups are not automatically cleaned up when their parent is destroyed. While configfs removes the dentries, it does not automatically drop the reference counts of the default groups. If the driver does not explicitly drop these references, the configfs items (and their dynamically allocated memory) will leak.

In the past, similar issues in the USB gadget subsystem and other configfs users were addressed using two main patterns:

1. **Manually dropping references recursively:**
   In commit `efbf0af70b4f` ("usb: gadget: uvc: configfs: Allocate groups dynamically"), the UVC gadget driver was refactored to dynamically allocate its configfs groups. To prevent memory leaks, the developers introduced a custom `uvcg_config_remove_children()` function. This function manually iterates over the `default_groups` list of a parent, removes each child from the list, recursively cleans up the child's children, and finally calls `config_item_put()` to drop the reference count and trigger the release function.

2. **Manually freeing the child's memory in the parent's release function:**
   In commit `ff74745e6d3d` ("usb: gadget: configfs: Fix memory leak of interface directory data"), a memory leak of the `os_desc` default group in the RNDIS function was fixed. Because the `os_desc` group did not have a dedicated configfs `release` callback, the developers fixed the leak by saving a pointer to the dynamically allocated group and explicitly calling `kfree()` on it inside the parent's release function (`rndis_free_inst`). 
   A similar fix was applied outside the USB subsystem in commit `3d2825c8c610` ("fs: dlm: fix configfs memory leak"), where a default group's memory was manually freed in the parent's release function because `configfs_remove_default_groups()` alone wouldn't free the memory without a release callback.

### Recommended Fix Strategy

For the `f_midi2` bug, the proposed fix of calling `configfs_remove_default_groups()` is the most idiomatic and robust approach. 

Unlike the RNDIS or DLM bugs mentioned above, the `ep.0` and `block.0` groups in `f_midi2` **already have** proper configfs release callbacks implemented (`f_midi2_ep_opts_release` and `f_midi2_block_opts_release` respectively), which correctly call `kfree()`. 

Therefore, you do not need to manually `kfree()` the child structures or write a custom recursive cleanup function like UVC did. You should follow the pattern of explicitly unrolling the default groups by calling `configfs_remove_default_groups()` in the respective parent's release functions:
- Call it in `f_midi2_free_inst()` to drop the refcount of `ep.0`.
- Call it in `f_midi2_ep_opts_release()` to drop the refcount of `block.0`.

This will correctly drop the reference counts, trigger the existing release callbacks, and safely free the dynamically allocated memory in the correct order.

130/2 2026/07/30 14:12 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 6080
							output: 37
							thoughts: 204
						

Thoughts:
Okay, let's see what we've got here.

**Analyzing a Memory Leak Fix**

Right, so we're dealing with a memory leak in `drivers/usb/gadget/function/f_midi2.c`. The root cause is pretty clear: missing calls to `configfs_remove_default_groups()` within the release functions of configfs items or groups. Specifically, we need to add that call in `f_midi2_free_inst()` and `f_midi2_ep_opts_release()`. Seems straightforward enough.

Now, before I just blindly implement the fix, I want to make sure we're addressing the *actual* problem and not just a symptom. Let's see if we can find similar issues that have been addressed in the past. We need to identify any prior fixes for similar `configfs` memory leaks, especially within related subsystems or files. I'll focus our search on `drivers/usb/gadget/`, `drivers/usb/`, or the kernel more generally for any occurrences of missing calls in similar functions.

Okay, let's use `git log`. Given the potential for this kind of bug to have existed for a while, I'll go back at least three years with `Since="3 years"`. I'll focus on diffs containing `configfs_remove_default_groups`. I'm pretty sure that should give us what we need to get a clear perspective on this. Let's see what we find.



131/2 2026/07/30 14:12 tool git-log
4m Args:
map[CodeRegexp:configfs_remove_default_groups Count:20 Since:3 years]

Results:
map[Output:]

132/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 6652
							output: 22
							thoughts: 54
						

Thoughts:
Okay, here's my thought process on that query:

**Digging into the `configfs_remove_default_groups` Query**

Hmm, no hits for `configfs_remove_default_groups` in the last three years? That's... interesting. It's either an indication that this particular function isn't frequently used, or, more likely, my search parameters (specifically, the regex I employed) are off. Before I start going down a rabbit hole, the logical first step is to definitively determine if the function *even exists* within the codebase. It could be that it's been deprecated, renamed, or isn't part of the active project I'm focusing on. So, let me just double-check that the function itself is actually defined before I start trying to determine when it was used.



133/2 2026/07/30 14:17 tool grepper
0m Args:
map[Expression:configfs_remove_default_groups]

Results:
map[Output:drivers/infiniband/core/cma_configfs.c=318=static void drop_cma_dev(struct config_group *cgroup, struct config_item *item)
--
drivers/infiniband/core/cma_configfs.c-324-
drivers/infiniband/core/cma_configfs.c:325:	configfs_remove_default_groups(&cma_dev_group->ports_group);
drivers/infiniband/core/cma_configfs.c:326:	configfs_remove_default_groups(&cma_dev_group->device_group);
drivers/infiniband/core/cma_configfs.c-327-	config_item_put(item);
--
drivers/target/target_core_configfs.c=267=static void target_core_deregister_fabric(
--
drivers/target/target_core_configfs.c-283-
drivers/target/target_core_configfs.c:284:	configfs_remove_default_groups(&tf->tf_group);
drivers/target/target_core_configfs.c-285-	config_item_put(item);
--
drivers/target/target_core_configfs.c=3502=static void target_core_drop_subdev(
--
drivers/target/target_core_configfs.c-3514-
drivers/target/target_core_configfs.c:3515:	configfs_remove_default_groups(&dev->dev_stat_grps.stat_group);
drivers/target/target_core_configfs.c:3516:	configfs_remove_default_groups(&dev->t10_alua.alua_tg_pt_gps_group);
drivers/target/target_core_configfs.c-3517-
--
drivers/target/target_core_configfs.c-3523-
drivers/target/target_core_configfs.c:3524:	configfs_remove_default_groups(dev_cg);
drivers/target/target_core_configfs.c-3525-
--
drivers/target/target_core_configfs.c=3843=static void __exit target_core_exit_configfs(void)
drivers/target/target_core_configfs.c-3844-{
drivers/target/target_core_configfs.c:3845:	configfs_remove_default_groups(&alua_lu_gps_group);
drivers/target/target_core_configfs.c:3846:	configfs_remove_default_groups(&alua_group);
drivers/target/target_core_configfs.c:3847:	configfs_remove_default_groups(&target_core_hbagroup);
drivers/target/target_core_configfs.c-3848-
--
drivers/target/target_core_fabric_configfs.c=326=static void target_fabric_drop_mappedlun(
--
drivers/target/target_core_fabric_configfs.c-332-
drivers/target/target_core_fabric_configfs.c:333:	configfs_remove_default_groups(&lacl->ml_stat_grps.stat_group);
drivers/target/target_core_fabric_configfs.c:334:	configfs_remove_default_groups(&lacl->se_lun_group);
drivers/target/target_core_fabric_configfs.c-335-
--
drivers/target/target_core_fabric_configfs.c=339=static void target_fabric_nacl_base_release(struct config_item *item)
--
drivers/target/target_core_fabric_configfs.c-343-
drivers/target/target_core_fabric_configfs.c:344:	configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
drivers/target/target_core_fabric_configfs.c-345-	core_tpg_del_initiator_node_acl(se_nacl);
--
drivers/target/target_core_fabric_configfs.c=373=static struct config_group *target_fabric_make_nodeacl(
--
drivers/target/target_core_fabric_configfs.c-411-		if (ret) {
drivers/target/target_core_fabric_configfs.c:412:			configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
drivers/target/target_core_fabric_configfs.c-413-			core_tpg_del_initiator_node_acl(se_nacl);
--
drivers/target/target_core_fabric_configfs.c=421=static void target_fabric_drop_nodeacl(
--
drivers/target/target_core_fabric_configfs.c-427-
drivers/target/target_core_fabric_configfs.c:428:	configfs_remove_default_groups(&se_nacl->acl_group);
drivers/target/target_core_fabric_configfs.c-429-
--
drivers/target/target_core_fabric_configfs.c=777=static void target_fabric_drop_lun(
--
drivers/target/target_core_fabric_configfs.c-783-
drivers/target/target_core_fabric_configfs.c:784:	configfs_remove_default_groups(&lun->port_stat_grps.stat_group);
drivers/target/target_core_fabric_configfs.c:785:	configfs_remove_default_groups(&lun->lun_group);
drivers/target/target_core_fabric_configfs.c-786-
--
drivers/target/target_core_fabric_configfs.c=979=static void target_fabric_drop_tpg(
--
drivers/target/target_core_fabric_configfs.c-985-
drivers/target/target_core_fabric_configfs.c:986:	configfs_remove_default_groups(&se_tpg->tpg_group);
drivers/target/target_core_fabric_configfs.c-987-	config_item_put(item);
--
drivers/target/target_core_fabric_configfs.c=990=static void target_fabric_release_wwn(struct config_item *item)
--
drivers/target/target_core_fabric_configfs.c-995-
drivers/target/target_core_fabric_configfs.c:996:	configfs_remove_default_groups(&wwn->fabric_stat_group);
drivers/target/target_core_fabric_configfs.c:997:	configfs_remove_default_groups(&wwn->param_group);
drivers/target/target_core_fabric_configfs.c-998-	tf->tf_ops->fabric_drop_wwn(wwn);
--
drivers/target/target_core_fabric_configfs.c=1160=static void target_fabric_drop_wwn(
--
drivers/target/target_core_fabric_configfs.c-1166-
drivers/target/target_core_fabric_configfs.c:1167:	configfs_remove_default_groups(&wwn->wwn_group);
drivers/target/target_core_fabric_configfs.c-1168-	config_item_put(item);
--
fs/configfs/dir.c=734=static int populate_groups(struct config_group *group,
--
fs/configfs/dir.c-747-
fs/configfs/dir.c:748:void configfs_remove_default_groups(struct config_group *group)
fs/configfs/dir.c-749-{
--
fs/configfs/dir.c-756-}
fs/configfs/dir.c:757:EXPORT_SYMBOL(configfs_remove_default_groups);
fs/configfs/dir.c-758-
--
fs/dlm/config.c=457=static void drop_cluster(struct config_group *g, struct config_item *i)
--
fs/dlm/config.c-460-
fs/dlm/config.c:461:	configfs_remove_default_groups(&cl->group);
fs/dlm/config.c-462-
--
fs/dlm/config.c=507=static void drop_space(struct config_group *g, struct config_item *i)
--
fs/dlm/config.c-512-
fs/dlm/config.c:513:	configfs_remove_default_groups(&sp->group);
fs/dlm/config.c-514-	config_item_put(i);
--
fs/ocfs2/cluster/nodemanager.c=733=static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item)
--
fs/ocfs2/cluster/nodemanager.c-739-
fs/ocfs2/cluster/nodemanager.c:740:	configfs_remove_default_groups(&cluster->cl_group);
fs/ocfs2/cluster/nodemanager.c-741-	config_item_put(item);
--
include/linux/configfs.h=245=void configfs_unregister_group(struct config_group *group);
include/linux/configfs.h-246-
include/linux/configfs.h:247:void configfs_remove_default_groups(struct config_group *group);
include/linux/configfs.h-248-
]

134/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 9345
							output: 22
							thoughts: 136
						

Thoughts:
**Investigating USB Gadget Driver Default Group Handling**

Alright, I'm diving into this `configfs_remove_default_groups` function. My initial scan shows its utilization within the `drivers/infiniband`, `drivers/target`, `fs/dlm`, and `fs/ocfs2` directories. That's a good starting point. But I immediately think, what about the USB gadget drivers? My mind instinctively goes there.

Let me just quickly search the `drivers/usb/gadget/` directory for that function name… Hmm, no results. Interesting. Now I'm really curious. If `configfs_remove_default_groups` isn't used, how are those USB gadget functions managing default groups? Are they handling it differently? Or are they perhaps relying on some other mechanism entirely?

Okay, let's back up and broaden the search. Let's see if other USB gadget functions even *use* default groups at all. I need to understand the fundamental approach they are taking to this aspect of the configuration. Let's explore.



135/2 2026/07/30 14:17 tool grepper
0m Args:
map[Expression:configfs_add_default_group]

Results:
map[Output:Documentation/filesystems/configfs.rst=449=A configfs subsystem specifies default groups by adding them using the
Documentation/filesystems/configfs.rst:450:configfs_add_default_group() function to the parent config_group
Documentation/filesystems/configfs.rst-451-structure.  Each added group is populated in the configfs tree at the same
--
drivers/block/null_blk/main.c=657=static void nullb_add_fault_config(struct nullb_device *dev)
--
drivers/block/null_blk/main.c-662-
drivers/block/null_blk/main.c:663:	configfs_add_default_group(&dev->timeout_config.group, &dev->group);
drivers/block/null_blk/main.c:664:	configfs_add_default_group(&dev->requeue_config.group, &dev->group);
drivers/block/null_blk/main.c:665:	configfs_add_default_group(&dev->init_hctx_fault_config.group, &dev->group);
drivers/block/null_blk/main.c-666-}
--
drivers/gpu/drm/vkms/vkms_configfs.c=358=static struct config_group *make_plane_group(struct config_group *group,
--
drivers/gpu/drm/vkms/vkms_configfs.c-388-					    &plane_possible_crtcs_group_type);
drivers/gpu/drm/vkms/vkms_configfs.c:389:		configfs_add_default_group(&plane->possible_crtcs_group,
drivers/gpu/drm/vkms/vkms_configfs.c-390-					   &plane->group);
--
drivers/gpu/drm/vkms/vkms_configfs.c=474=static struct config_group *make_encoder_group(struct config_group *group,
--
drivers/gpu/drm/vkms/vkms_configfs.c-505-					    &encoder_possible_crtcs_group_type);
drivers/gpu/drm/vkms/vkms_configfs.c:506:		configfs_add_default_group(&encoder->possible_crtcs_group,
drivers/gpu/drm/vkms/vkms_configfs.c-507-					   &encoder->group);
--
drivers/gpu/drm/vkms/vkms_configfs.c=641=static struct config_group *make_connector_group(struct config_group *group,
--
drivers/gpu/drm/vkms/vkms_configfs.c-672-					    &connector_possible_encoders_group_type);
drivers/gpu/drm/vkms/vkms_configfs.c:673:		configfs_add_default_group(&connector->possible_encoders_group,
drivers/gpu/drm/vkms/vkms_configfs.c-674-					   &connector->group);
--
drivers/gpu/drm/vkms/vkms_configfs.c=763=static struct config_group *make_device_group(struct config_group *group,
--
drivers/gpu/drm/vkms/vkms_configfs.c-787-				    &plane_group_type);
drivers/gpu/drm/vkms/vkms_configfs.c:788:	configfs_add_default_group(&dev->planes_group, &dev->group);
drivers/gpu/drm/vkms/vkms_configfs.c-789-
--
drivers/gpu/drm/vkms/vkms_configfs.c-791-				    &crtc_group_type);
drivers/gpu/drm/vkms/vkms_configfs.c:792:	configfs_add_default_group(&dev->crtcs_group, &dev->group);
drivers/gpu/drm/vkms/vkms_configfs.c-793-
--
drivers/gpu/drm/vkms/vkms_configfs.c-795-				    &encoder_group_type);
drivers/gpu/drm/vkms/vkms_configfs.c:796:	configfs_add_default_group(&dev->encoders_group, &dev->group);
drivers/gpu/drm/vkms/vkms_configfs.c-797-
--
drivers/gpu/drm/vkms/vkms_configfs.c-799-				    &connector_group_type);
drivers/gpu/drm/vkms/vkms_configfs.c:800:	configfs_add_default_group(&dev->connectors_group, &dev->group);
drivers/gpu/drm/vkms/vkms_configfs.c-801-
--
drivers/gpu/drm/xe/xe_configfs.c=982=static struct config_group *xe_config_make_device_group(struct config_group *group,
--
drivers/gpu/drm/xe/xe_configfs.c-1048-		config_group_init_type_name(&dev->sriov, "sriov", &xe_config_sriov_type);
drivers/gpu/drm/xe/xe_configfs.c:1049:		configfs_add_default_group(&dev->sriov, &dev->group);
drivers/gpu/drm/xe/xe_configfs.c-1050-	}
--
drivers/hwtracing/coresight/coresight-syscfg-configfs.c=178=static int cscfg_add_preset_groups(struct cscfg_fs_config *cfg_view)
--
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-199-					    &cscfg_config_preset_type);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c:200:		configfs_add_default_group(&cfg_fs_preset->group, &cfg_view->group);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-201-	}
--
drivers/hwtracing/coresight/coresight-syscfg-configfs.c=322=static int cscfg_create_params_group_items(struct cscfg_feature_desc *feat_desc,
--
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-338-					    &cscfg_param_view_type);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c:339:		configfs_add_default_group(&param_item->group, params_group);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-340-	}
--
drivers/hwtracing/coresight/coresight-syscfg-configfs.c=344=static struct config_group *cscfg_create_feature_group(struct cscfg_feature_desc *feat_desc)
--
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-374-		config_group_init_type_name(params_group, "params", params_group_type);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c:375:		configfs_add_default_group(params_group, &feat_view->group);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-376-		item_err = cscfg_create_params_group_items(feat_desc, params_group);
--
drivers/hwtracing/coresight/coresight-syscfg-configfs.c=451=int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr)
--
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-471-	config_group_init(&cscfg_configs_grp);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c:472:	configfs_add_default_group(&cscfg_configs_grp, &subsys->su_group);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-473-
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-474-	config_group_init(&cscfg_features_grp);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c:475:	configfs_add_default_group(&cscfg_features_grp, &subsys->su_group);
drivers/hwtracing/coresight/coresight-syscfg-configfs.c-476-
--
drivers/infiniband/core/cma_configfs.c=199=static int make_cma_ports(struct cma_dev_group *cma_dev_group,
--
drivers/infiniband/core/cma_configfs.c-226-					    &cma_port_group_type);
drivers/infiniband/core/cma_configfs.c:227:		configfs_add_default_group(&ports[i].group,
drivers/infiniband/core/cma_configfs.c-228-				&cma_dev_group->ports_group);
--
drivers/infiniband/core/cma_configfs.c=276=static struct config_group *make_cma_dev(struct config_group *group,
--
drivers/infiniband/core/cma_configfs.c-304-				    &cma_device_group_type);
drivers/infiniband/core/cma_configfs.c:305:	configfs_add_default_group(&cma_dev_group->ports_group,
drivers/infiniband/core/cma_configfs.c-306-			&cma_dev_group->device_group);
--
drivers/net/netconsole.c=1409=static void init_target_config_group(struct netconsole_target *nt,
--
drivers/net/netconsole.c-1414-				    &userdata_type);
drivers/net/netconsole.c:1415:	configfs_add_default_group(&nt->userdata_group, &nt->group);
drivers/net/netconsole.c-1416-}
--
drivers/nvme/target/configfs.c=1038=static void nvmet_add_passthru_group(struct nvmet_subsys *subsys)
--
drivers/nvme/target/configfs.c-1041-				    "passthru", &nvmet_passthru_type);
drivers/nvme/target/configfs.c:1042:	configfs_add_default_group(&subsys->passthru_group,
drivers/nvme/target/configfs.c-1043-				   &subsys->group);
--
drivers/nvme/target/configfs.c=1734=static struct config_group *nvmet_subsys_make(struct config_group *group,
--
drivers/nvme/target/configfs.c-1756-			"namespaces", &nvmet_namespaces_type);
drivers/nvme/target/configfs.c:1757:	configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
drivers/nvme/target/configfs.c-1758-
--
drivers/nvme/target/configfs.c-1760-			"allowed_hosts", &nvmet_allowed_hosts_type);
drivers/nvme/target/configfs.c:1761:	configfs_add_default_group(&subsys->allowed_hosts_group,
drivers/nvme/target/configfs.c-1762-			&subsys->group);
--
drivers/nvme/target/configfs.c=2039=static struct config_group *nvmet_ports_make(struct config_group *group,
--
drivers/nvme/target/configfs.c-2084-			"subsystems", &nvmet_port_subsys_type);
drivers/nvme/target/configfs.c:2085:	configfs_add_default_group(&port->subsys_group, &port->group);
drivers/nvme/target/configfs.c-2086-
--
drivers/nvme/target/configfs.c-2088-			"referrals", &nvmet_referrals_type);
drivers/nvme/target/configfs.c:2089:	configfs_add_default_group(&port->referrals_group, &port->group);
drivers/nvme/target/configfs.c-2090-
--
drivers/nvme/target/configfs.c-2092-			"ana_groups", &nvmet_ana_groups_type);
drivers/nvme/target/configfs.c:2093:	configfs_add_default_group(&port->ana_groups_group, &port->group);
drivers/nvme/target/configfs.c-2094-
--
drivers/nvme/target/configfs.c-2099-			&nvmet_ana_group_type);
drivers/nvme/target/configfs.c:2100:	configfs_add_default_group(&port->ana_default_group.group,
drivers/nvme/target/configfs.c-2101-			&port->ana_groups_group);
--
drivers/nvme/target/configfs.c=2363=int __init nvmet_init_configfs(void)
--
drivers/nvme/target/configfs.c-2371-			"subsystems", &nvmet_subsystems_type);
drivers/nvme/target/configfs.c:2372:	configfs_add_default_group(&nvmet_subsystems_group,
drivers/nvme/target/configfs.c-2373-			&nvmet_configfs_subsystem.su_group);
--
drivers/nvme/target/configfs.c-2376-			"ports", &nvmet_ports_type);
drivers/nvme/target/configfs.c:2377:	configfs_add_default_group(&nvmet_ports_group,
drivers/nvme/target/configfs.c-2378-			&nvmet_configfs_subsystem.su_group);
--
drivers/nvme/target/configfs.c-2381-			"hosts", &nvmet_hosts_type);
drivers/nvme/target/configfs.c:2382:	configfs_add_default_group(&nvmet_hosts_group,
drivers/nvme/target/configfs.c-2383-			&nvmet_configfs_subsystem.su_group);
--
drivers/pci/endpoint/pci-ep-cfs.c=97=static struct config_group
--
drivers/pci/endpoint/pci-ep-cfs.c-104-				    &pci_secondary_epc_type);
drivers/pci/endpoint/pci-ep-cfs.c:105:	configfs_add_default_group(secondary_epc_group, &epf_group->group);
drivers/pci/endpoint/pci-ep-cfs.c-106-
--
drivers/pci/endpoint/pci-ep-cfs.c=161=static struct config_group
--
drivers/pci/endpoint/pci-ep-cfs.c-167-				    &pci_primary_epc_type);
drivers/pci/endpoint/pci-ep-cfs.c:168:	configfs_add_default_group(primary_epc_group, &epf_group->group);
drivers/pci/endpoint/pci-ep-cfs.c-169-
--
drivers/pci/endpoint/pci-ep-cfs.c=558=static void pci_ep_cfs_add_type_group(struct pci_epf_group *epf_group)
--
drivers/pci/endpoint/pci-ep-cfs.c-572-
drivers/pci/endpoint/pci-ep-cfs.c:573:	configfs_add_default_group(group, &epf_group->group);
drivers/pci/endpoint/pci-ep-cfs.c-574-}
--
drivers/target/iscsi/iscsi_target_configfs.c=725=static int lio_target_init_nodeacl(struct se_node_acl *se_nacl,
--
drivers/target/iscsi/iscsi_target_configfs.c-731-			"iscsi_sess_stats", &iscsi_stat_sess_cit);
drivers/target/iscsi/iscsi_target_configfs.c:732:	configfs_add_default_group(&acl->node_stat_grps.iscsi_sess_stats_group,
drivers/target/iscsi/iscsi_target_configfs.c-733-			&se_nacl->acl_fabric_stat_group);
--
drivers/target/iscsi/iscsi_target_configfs.c=1202=static void lio_target_add_wwn_groups(struct se_wwn *wwn)
--
drivers/target/iscsi/iscsi_target_configfs.c-1207-			"iscsi_instance", &iscsi_stat_instance_cit);
drivers/target/iscsi/iscsi_target_configfs.c:1208:	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_instance_group,
drivers/target/iscsi/iscsi_target_configfs.c-1209-			&tiqn->tiqn_wwn.fabric_stat_group);
--
drivers/target/iscsi/iscsi_target_configfs.c-1212-			"iscsi_sess_err", &iscsi_stat_sess_err_cit);
drivers/target/iscsi/iscsi_target_configfs.c:1213:	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_sess_err_group,
drivers/target/iscsi/iscsi_target_configfs.c-1214-			&tiqn->tiqn_wwn.fabric_stat_group);
--
drivers/target/iscsi/iscsi_target_configfs.c-1217-			"iscsi_tgt_attr", &iscsi_stat_tgt_attr_cit);
drivers/target/iscsi/iscsi_target_configfs.c:1218:	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_tgt_attr_group,
drivers/target/iscsi/iscsi_target_configfs.c-1219-			&tiqn->tiqn_wwn.fabric_stat_group);
--
drivers/target/iscsi/iscsi_target_configfs.c-1222-			"iscsi_login_stats", &iscsi_stat_login_cit);
drivers/target/iscsi/iscsi_target_configfs.c:1223:	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_login_stats_group,
drivers/target/iscsi/iscsi_target_configfs.c-1224-			&tiqn->tiqn_wwn.fabric_stat_group);
--
drivers/target/iscsi/iscsi_target_configfs.c-1227-			"iscsi_logout_stats", &iscsi_stat_logout_cit);
drivers/target/iscsi/iscsi_target_configfs.c:1228:	configfs_add_default_group(&tiqn->tiqn_stat_grps.iscsi_logout_stats_group,
drivers/target/iscsi/iscsi_target_configfs.c-1229-			&tiqn->tiqn_wwn.fabric_stat_group);
--
drivers/target/target_core_configfs.c=182=static struct config_group *target_core_register_fabric(
--
drivers/target/target_core_configfs.c-256-			&tf->tf_discovery_cit);
drivers/target/target_core_configfs.c:257:	configfs_add_default_group(&tf->tf_disc_group, &tf->tf_group);
drivers/target/target_core_configfs.c-258-
--
drivers/target/target_core_configfs.c=3422=static struct config_group *target_core_make_subdev(
--
drivers/target/target_core_configfs.c-3444-			&tb->tb_dev_action_cit);
drivers/target/target_core_configfs.c:3445:	configfs_add_default_group(&dev->dev_action_group, &dev->dev_group);
drivers/target/target_core_configfs.c-3446-
--
drivers/target/target_core_configfs.c-3448-			&tb->tb_dev_attrib_cit);
drivers/target/target_core_configfs.c:3449:	configfs_add_default_group(&dev->dev_attrib.da_group, &dev->dev_group);
drivers/target/target_core_configfs.c-3450-
--
drivers/target/target_core_configfs.c-3452-			&tb->tb_dev_pr_cit);
drivers/target/target_core_configfs.c:3453:	configfs_add_default_group(&dev->dev_pr_group, &dev->dev_group);
drivers/target/target_core_configfs.c-3454-
--
drivers/target/target_core_configfs.c-3456-			&tb->tb_dev_wwn_cit);
drivers/target/target_core_configfs.c:3457:	configfs_add_default_group(&dev->t10_wwn.t10_wwn_group,
drivers/target/target_core_configfs.c-3458-			&dev->dev_group);
--
drivers/target/target_core_configfs.c-3461-			"alua", &tb->tb_dev_alua_tg_pt_gps_cit);
drivers/target/target_core_configfs.c:3462:	configfs_add_default_group(&dev->t10_alua.alua_tg_pt_gps_group,
drivers/target/target_core_configfs.c-3463-			&dev->dev_group);
--
drivers/target/target_core_configfs.c-3466-			"statistics", &tb->tb_dev_stat_cit);
drivers/target/target_core_configfs.c:3467:	configfs_add_default_group(&dev->dev_stat_grps.stat_group,
drivers/target/target_core_configfs.c-3468-			&dev->dev_group);
--
drivers/target/target_core_configfs.c-3479-			"default_tg_pt_gp", &target_core_alua_tg_pt_gp_cit);
drivers/target/target_core_configfs.c:3480:	configfs_add_default_group(&tg_pt_gp->tg_pt_gp_group,
drivers/target/target_core_configfs.c-3481-			&dev->t10_alua.alua_tg_pt_gps_group);
--
drivers/target/target_core_configfs.c=3744=static int __init target_core_init_configfs(void)
--
drivers/target/target_core_configfs.c-3765-			&target_core_cit);
drivers/target/target_core_configfs.c:3766:	configfs_add_default_group(&target_core_hbagroup, &subsys->su_group);
drivers/target/target_core_configfs.c-3767-
--
drivers/target/target_core_configfs.c-3771-	config_group_init_type_name(&alua_group, "alua", &target_core_alua_cit);
drivers/target/target_core_configfs.c:3772:	configfs_add_default_group(&alua_group, &target_core_hbagroup);
drivers/target/target_core_configfs.c-3773-
--
drivers/target/target_core_configfs.c-3779-			&target_core_alua_lu_gps_cit);
drivers/target/target_core_configfs.c:3780:	configfs_add_default_group(&alua_lu_gps_group, &alua_group);
drivers/target/target_core_configfs.c-3781-
--
drivers/target/target_core_configfs.c-3792-				&target_core_alua_lu_gp_cit);
drivers/target/target_core_configfs.c:3793:	configfs_add_default_group(&lu_gp->lu_gp_group, &alua_lu_gps_group);
drivers/target/target_core_configfs.c-3794-
--
drivers/target/target_core_fabric_configfs.c=265=static struct config_group *target_fabric_make_mappedlun(
--
drivers/target/target_core_fabric_configfs.c-312-			"statistics", &tf->tf_tpg_mappedlun_stat_cit);
drivers/target/target_core_fabric_configfs.c:313:	configfs_add_default_group(&lacl->ml_stat_grps.stat_group,
drivers/target/target_core_fabric_configfs.c-314-			&lacl->se_lun_group);
--
drivers/target/target_core_fabric_configfs.c=373=static struct config_group *target_fabric_make_nodeacl(
--
drivers/target/target_core_fabric_configfs.c-390-			&tf->tf_tpg_nacl_attrib_cit);
drivers/target/target_core_fabric_configfs.c:391:	configfs_add_default_group(&se_nacl->acl_attrib_group,
drivers/target/target_core_fabric_configfs.c-392-			&se_nacl->acl_group);
--
drivers/target/target_core_fabric_configfs.c-395-			&tf->tf_tpg_nacl_auth_cit);
drivers/target/target_core_fabric_configfs.c:396:	configfs_add_default_group(&se_nacl->acl_auth_group,
drivers/target/target_core_fabric_configfs.c-397-			&se_nacl->acl_group);
--
drivers/target/target_core_fabric_configfs.c-400-			&tf->tf_tpg_nacl_param_cit);
drivers/target/target_core_fabric_configfs.c:401:	configfs_add_default_group(&se_nacl->acl_param_group,
drivers/target/target_core_fabric_configfs.c-402-			&se_nacl->acl_group);
--
drivers/target/target_core_fabric_configfs.c-405-			"fabric_statistics", &tf->tf_tpg_nacl_stat_cit);
drivers/target/target_core_fabric_configfs.c:406:	configfs_add_default_group(&se_nacl->acl_fabric_stat_group,
drivers/target/target_core_fabric_configfs.c-407-			&se_nacl->acl_group);
--
drivers/target/target_core_fabric_configfs.c=740=static struct config_group *target_fabric_make_lun(
--
drivers/target/target_core_fabric_configfs.c-768-			"statistics", &tf->tf_tpg_port_stat_cit);
drivers/target/target_core_fabric_configfs.c:769:	configfs_add_default_group(&lun->port_stat_grps.stat_group,
drivers/target/target_core_fabric_configfs.c-770-			&lun->lun_group);
--
drivers/target/target_core_fabric_configfs.c=926=static struct config_group *target_fabric_make_tpg(
--
drivers/target/target_core_fabric_configfs.c-947-			&tf->tf_tpg_lun_cit);
drivers/target/target_core_fabric_configfs.c:948:	configfs_add_default_group(&se_tpg->tpg_lun_group,
drivers/target/target_core_fabric_configfs.c-949-			&se_tpg->tpg_group);
--
drivers/target/target_core_fabric_configfs.c-952-			&tf->tf_tpg_np_cit);
drivers/target/target_core_fabric_configfs.c:953:	configfs_add_default_group(&se_tpg->tpg_np_group,
drivers/target/target_core_fabric_configfs.c-954-			&se_tpg->tpg_group);
--
drivers/target/target_core_fabric_configfs.c-957-			&tf->tf_tpg_nacl_cit);
drivers/target/target_core_fabric_configfs.c:958:	configfs_add_default_group(&se_tpg->tpg_acl_group,
drivers/target/target_core_fabric_configfs.c-959-			&se_tpg->tpg_group);
--
drivers/target/target_core_fabric_configfs.c-962-			&tf->tf_tpg_attrib_cit);
drivers/target/target_core_fabric_configfs.c:963:	configfs_add_default_group(&se_tpg->tpg_attrib_group,
drivers/target/target_core_fabric_configfs.c-964-			&se_tpg->tpg_group);
--
drivers/target/target_core_fabric_configfs.c-967-			&tf->tf_tpg_auth_cit);
drivers/target/target_core_fabric_configfs.c:968:	configfs_add_default_group(&se_tpg->tpg_auth_group,
drivers/target/target_core_fabric_configfs.c-969-			&se_tpg->tpg_group);
--
drivers/target/target_core_fabric_configfs.c-972-			&tf->tf_tpg_param_cit);
drivers/target/target_core_fabric_configfs.c:973:	configfs_add_default_group(&se_tpg->tpg_param_group,
drivers/target/target_core_fabric_configfs.c-974-			&se_tpg->tpg_group);
--
drivers/target/target_core_fabric_configfs.c=1125=static struct config_group *target_fabric_make_wwn(
--
drivers/target/target_core_fabric_configfs.c-1148-			&tf->tf_wwn_fabric_stats_cit);
drivers/target/target_core_fabric_configfs.c:1149:	configfs_add_default_group(&wwn->fabric_stat_group, &wwn->wwn_group);
drivers/target/target_core_fabric_configfs.c-1150-
--
drivers/target/target_core_fabric_configfs.c-1152-			&tf->tf_wwn_param_cit);
drivers/target/target_core_fabric_configfs.c:1153:	configfs_add_default_group(&wwn->param_group, &wwn->wwn_group);
drivers/target/target_core_fabric_configfs.c-1154-
--
drivers/target/target_core_stat.c=396=void target_stat_setup_dev_default_groups(struct se_device *dev)
--
drivers/target/target_core_stat.c-399-			"scsi_dev", &target_stat_scsi_dev_cit);
drivers/target/target_core_stat.c:400:	configfs_add_default_group(&dev->dev_stat_grps.scsi_dev_group,
drivers/target/target_core_stat.c-401-			&dev->dev_stat_grps.stat_group);
--
drivers/target/target_core_stat.c-404-			"scsi_tgt_dev", &target_stat_scsi_tgt_dev_cit);
drivers/target/target_core_stat.c:405:	configfs_add_default_group(&dev->dev_stat_grps.scsi_tgt_dev_group,
drivers/target/target_core_stat.c-406-			&dev->dev_stat_grps.stat_group);
--
drivers/target/target_core_stat.c-409-			"scsi_lu", &target_stat_scsi_lu_cit);
drivers/target/target_core_stat.c:410:	configfs_add_default_group(&dev->dev_stat_grps.scsi_lu_group,
drivers/target/target_core_stat.c-411-			&dev->dev_stat_grps.stat_group);
--
drivers/target/target_core_stat.c=803=void target_stat_setup_port_default_groups(struct se_lun *lun)
--
drivers/target/target_core_stat.c-806-			"scsi_port", &target_stat_scsi_port_cit);
drivers/target/target_core_stat.c:807:	configfs_add_default_group(&lun->port_stat_grps.scsi_port_group,
drivers/target/target_core_stat.c-808-			&lun->port_stat_grps.stat_group);
--
drivers/target/target_core_stat.c-811-			"scsi_tgt_port", &target_stat_scsi_tgt_port_cit);
drivers/target/target_core_stat.c:812:	configfs_add_default_group(&lun->port_stat_grps.scsi_tgt_port_group,
drivers/target/target_core_stat.c-813-			&lun->port_stat_grps.stat_group);
--
drivers/target/target_core_stat.c-816-			"scsi_transport", &target_stat_scsi_transport_cit);
drivers/target/target_core_stat.c:817:	configfs_add_default_group(&lun->port_stat_grps.scsi_transport_group,
drivers/target/target_core_stat.c-818-			&lun->port_stat_grps.stat_group);
--
drivers/target/target_core_stat.c=1301=void target_stat_setup_mappedlun_default_groups(struct se_lun_acl *lacl)
--
drivers/target/target_core_stat.c-1304-			"scsi_auth_intr", &target_stat_scsi_auth_intr_cit);
drivers/target/target_core_stat.c:1305:	configfs_add_default_group(&lacl->ml_stat_grps.scsi_auth_intr_group,
drivers/target/target_core_stat.c-1306-			&lacl->ml_stat_grps.stat_group);
--
drivers/target/target_core_stat.c-1309-			"scsi_att_intr_port", &target_stat_scsi_att_intr_port_cit);
drivers/target/target_core_stat.c:1310:	configfs_add_default_group(&lacl->ml_stat_grps.scsi_att_intr_port_group,
drivers/target/target_core_stat.c-1311-			&lacl->ml_stat_grps.stat_group);
--
drivers/usb/gadget/configfs.c=696=static struct config_group *config_desc_make(
--
drivers/usb/gadget/configfs.c-748-			&gadget_config_name_strings_type);
drivers/usb/gadget/configfs.c:749:	configfs_add_default_group(&cfg->strings_group, &cfg->group);
drivers/usb/gadget/configfs.c-750-
--
drivers/usb/gadget/configfs.c=1525=struct config_group *usb_os_desc_prepare_interf_dir(
--
drivers/usb/gadget/configfs.c-1549-	config_group_init_type_name(os_desc_group, "os_desc", os_desc_type);
drivers/usb/gadget/configfs.c:1550:	configfs_add_default_group(os_desc_group, parent);
drivers/usb/gadget/configfs.c-1551-
--
drivers/usb/gadget/configfs.c-1563-				     names[n_interf]);
drivers/usb/gadget/configfs.c:1564:		configfs_add_default_group(&d->group, os_desc_group);
drivers/usb/gadget/configfs.c-1565-	}
--
drivers/usb/gadget/configfs.c=1988=static struct config_group *gadgets_make(
--
drivers/usb/gadget/configfs.c-2001-			&functions_type);
drivers/usb/gadget/configfs.c:2002:	configfs_add_default_group(&gi->functions_group, &gi->group);
drivers/usb/gadget/configfs.c-2003-
--
drivers/usb/gadget/configfs.c-2005-			&config_desc_type);
drivers/usb/gadget/configfs.c:2006:	configfs_add_default_group(&gi->configs_group, &gi->group);
drivers/usb/gadget/configfs.c-2007-
--
drivers/usb/gadget/configfs.c-2009-			&gadget_language_strings_type);
drivers/usb/gadget/configfs.c:2010:	configfs_add_default_group(&gi->strings_group, &gi->group);
drivers/usb/gadget/configfs.c-2011-
--
drivers/usb/gadget/configfs.c-2013-			&os_desc_type);
drivers/usb/gadget/configfs.c:2014:	configfs_add_default_group(&gi->os_desc_group, &gi->group);
drivers/usb/gadget/configfs.c-2015-
--
drivers/usb/gadget/configfs.c-2017-			&webusb_type);
drivers/usb/gadget/configfs.c:2018:	configfs_add_default_group(&gi->webusb_group, &gi->group);
drivers/usb/gadget/configfs.c-2019-
--
drivers/usb/gadget/function/f_mass_storage.c=3494=static struct usb_function_instance *fsg_alloc_inst(void)
--
drivers/usb/gadget/function/f_mass_storage.c-3530-	config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
drivers/usb/gadget/function/f_mass_storage.c:3531:	configfs_add_default_group(&opts->lun0.group, &opts->func_inst.group);
drivers/usb/gadget/function/f_mass_storage.c-3532-
--
drivers/usb/gadget/function/f_midi2.c=2647=static struct usb_function_instance *f_midi2_alloc_inst(void)
--
drivers/usb/gadget/function/f_midi2.c-2687-				    &f_midi2_ep_type);
drivers/usb/gadget/function/f_midi2.c:2688:	configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
drivers/usb/gadget/function/f_midi2.c-2689-
--
drivers/usb/gadget/function/f_midi2.c-2691-				    &f_midi2_block_type);
drivers/usb/gadget/function/f_midi2.c:2692:	configfs_add_default_group(&block_opts->group, &ep_opts->group);
drivers/usb/gadget/function/f_midi2.c-2693-
--
drivers/usb/gadget/function/uvc_configfs.c=156=static int uvcg_config_create_group(struct config_group *parent,
--
drivers/usb/gadget/function/uvc_configfs.c-165-	config_group_init_type_name(group, type->name, &type->type);
drivers/usb/gadget/function/uvc_configfs.c:166:	configfs_add_default_group(group, parent);
drivers/usb/gadget/function/uvc_configfs.c-167-
--
drivers/usb/gadget/function/uvc_configfs.c=1432=static int uvcg_control_class_create_children(struct config_group *parent)
--
drivers/usb/gadget/function/uvc_configfs.c-1447-					    &uvcg_control_class_type);
drivers/usb/gadget/function/uvc_configfs.c:1448:		configfs_add_default_group(&group->group, parent);
drivers/usb/gadget/function/uvc_configfs.c-1449-	}
--
drivers/usb/gadget/function/uvc_configfs.c=3096=static int uvcg_color_matching_create_children(struct config_group *parent)
--
drivers/usb/gadget/function/uvc_configfs.c-3112-				    &uvcg_color_matching_type);
drivers/usb/gadget/function/uvc_configfs.c:3113:	configfs_add_default_group(&color_match->group, parent);
drivers/usb/gadget/function/uvc_configfs.c-3114-
--
drivers/usb/gadget/function/uvc_configfs.c=3548=static int uvcg_streaming_class_create_children(struct config_group *parent)
--
drivers/usb/gadget/function/uvc_configfs.c-3563-					    &uvcg_streaming_class_type);
drivers/usb/gadget/function/uvc_configfs.c:3564:		configfs_add_default_group(&group->group, parent);
drivers/usb/gadget/function/uvc_configfs.c-3565-	}
--
fs/dlm/config.c=422=static struct config_group *make_cluster(struct config_group *g,
--
fs/dlm/config.c-442-
fs/dlm/config.c:443:	configfs_add_default_group(&sps->ss_group, &cl->group);
fs/dlm/config.c:444:	configfs_add_default_group(&cms->cs_group, &cl->group);
fs/dlm/config.c-445-
--
fs/dlm/config.c=478=static struct config_group *make_space(struct config_group *g, const char *name)
--
fs/dlm/config.c-491-	config_group_init_type_name(&nds->ns_group, "nodes", &nodes_type);
fs/dlm/config.c:492:	configfs_add_default_group(&nds->ns_group, &sp->group);
fs/dlm/config.c-493-
--
fs/ocfs2/cluster/nodemanager.c=686=static struct config_group *o2nm_cluster_group_make_group(struct config_group *group,
--
fs/ocfs2/cluster/nodemanager.c-705-				    &o2nm_cluster_type);
fs/ocfs2/cluster/nodemanager.c:706:	configfs_add_default_group(&ns->ns_group, &cluster->cl_group);
fs/ocfs2/cluster/nodemanager.c-707-
--
fs/ocfs2/cluster/nodemanager.c-709-				    &o2nm_node_group_type);
fs/ocfs2/cluster/nodemanager.c:710:	configfs_add_default_group(o2hb_group, &cluster->cl_group);
fs/ocfs2/cluster/nodemanager.c-711-
--
include/linux/configfs.h=105=extern struct config_item *config_group_find_item(struct config_group *,
--
include/linux/configfs.h-108-
include/linux/configfs.h:109:static inline void configfs_add_default_group(struct config_group *new_group,
include/linux/configfs.h-110-		struct config_group *group)
]

136/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 21383
							output: 44
							thoughts: 40
						

Thoughts:
Okay, here's my take on those thoughts, framed from my perspective:

**Diving into the ConfigFS Nuances**

Right, so I see `f_mass_storage.c` leveraging `configfs_add_default_group`. My first instinct, as always, is to follow the entire lifecycle, so I'm immediately interested in how they're handling the counterpart, `configfs_remove_default_groups`. Understanding the add is only half the battle; knowing the removal process is *critical* to ensuring proper resource cleanup and preventing any lingering issues. I need to dig into the relationship between these two to fully grasp the design philosophy and potential implications within the mass storage framework. I'm keen to see if there are any subtle nuances in that relationship that could cause problems down the line. It's time to check what's going on with the removal.



137/2 2026/07/30 14:17 tool grepper
0m Error:
no matches

Args:
map[Expression:configfs_remove_default_groups PathPrefix:drivers/usb/gadget/function/f_mass_storage.c]

Results:
map[Output:]

138/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 21665
							output: 46
							thoughts: 36
						

Thoughts:
Okay, let's see. My first thought is: **Hang on a second, that's not right**. I was under the impression that `f_mass_storage.c` should be using `configfs_remove_default_groups`. But now I'm questioning that assumption. I need to be absolutely sure. This warrants a closer look, especially focusing on how the storage instance is actually cleaned up and freed within this module. I need to trace the memory management in this specific context to confirm. I'm going to dig into the freeing process itself.



139/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_mass_storage.c Name:fsg_free_inst]

Results:
map[SourceCode:3485:	static void fsg_free_inst(struct usb_function_instance *fi)
3486:	{
3487:		struct fsg_opts *opts;
3488:	
3489:		opts = fsg_opts_from_func_inst(fi);
3490:		fsg_common_release(opts->common);
3491:		kfree(opts);
3492:	}
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

140/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 22019
							output: 46
							thoughts: 41
						

Thoughts:
Okay, let me think this through.

**Investigating a Potential Resource Leak in the File Storage Gadget (FSG)**

Alright, so I'm looking at `fsg_free_inst` and something immediately strikes me as odd. I'm wondering why this function doesn't seem to be calling `configfs_remove_default_groups`. That's a red flag.  Could it potentially be leaking resources in some way?  I need to dig deeper. I need to figure out *what* this module is doing, and if it's de-allocating everything correctly.

My next step is to examine `fsg_lun_drop`. That feels like the logical place to start tracing the resource cleanup path associated with a logical unit number (LUN) within the FSG context. I need to understand what's happening there, specifically, and see if the missing call to `configfs_remove_default_groups` becomes relevant in its control flow. I need to know if `fsg_lun_drop` *should* be handling those cleanup steps, or if the initial suspicion of a leak is incorrect. This is going to require careful inspection of the code.



141/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_mass_storage.c Name:fsg_lun_drop]

Results:
map[SourceCode:3349:	static void fsg_lun_drop(struct config_group *group, struct config_item *item)
3350:	{
3351:		struct fsg_lun_opts *lun_opts;
3352:		struct fsg_opts *fsg_opts;
3353:	
3354:		lun_opts = to_fsg_lun_opts(item);
3355:		fsg_opts = to_fsg_opts(&group->cg_item);
3356:	
3357:		mutex_lock(&fsg_opts->lock);
3358:		if (fsg_opts->refcnt) {
3359:			struct config_item *gadget;
3360:	
3361:			gadget = group->cg_item.ci_parent->ci_parent;
3362:			unregister_gadget_item(gadget);
3363:		}
3364:	
3365:		fsg_common_remove_lun(lun_opts->lun);
3366:		fsg_opts->common->luns[lun_opts->lun_id] = NULL;
3367:		lun_opts->lun_id = 0;
3368:		mutex_unlock(&fsg_opts->lock);
3369:	
3370:		config_item_put(item);
3371:	}
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

142/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 22761
							output: 46
							thoughts: 34
						

Thoughts:
Okay, let me think this through.

**Analyzing the Default Group Assignment in `fsg_alloc_inst`**

Hmm, hold on a second...it just hit me. I think I've spotted something potentially significant. I recall that `fsg_alloc_inst` automatically includes `lun.0` as a default group. This default group addition could have implications further down the line. I'd better confirm my recollection and understand the mechanics in greater detail. I need to take a look at the `fsg_alloc_inst` function specifically. Let's dig into that and see how this default group assignment is actually implemented. I want to confirm exactly how it's being handled and any knock-on effects that might result.



143/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_mass_storage.c Name:fsg_alloc_inst]

Results:
map[SourceCode:3494:	static struct usb_function_instance *fsg_alloc_inst(void)
3495:	{
3496:		struct fsg_opts *opts;
3497:		struct fsg_lun_config config;
3498:		int rc;
3499:	
3500:		opts = kzalloc_obj(*opts);
3501:		if (!opts)
3502:			return ERR_PTR(-ENOMEM);
3503:		mutex_init(&opts->lock);
3504:		opts->func_inst.free_func_inst = fsg_free_inst;
3505:		opts->common = fsg_common_setup(opts->common);
3506:		if (IS_ERR(opts->common)) {
3507:			rc = PTR_ERR(opts->common);
3508:			goto release_opts;
3509:		}
3510:	
3511:		rc = fsg_common_set_num_buffers(opts->common,
3512:						CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS);
3513:		if (rc)
3514:			goto release_common;
3515:	
3516:		pr_info(FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n");
3517:	
3518:		memset(&config, 0, sizeof(config));
3519:		config.removable = true;
3520:		rc = fsg_common_create_lun(opts->common, &config, 0, "lun.0",
3521:				(const char **)&opts->func_inst.group.cg_item.ci_name);
3522:		if (rc)
3523:			goto release_buffers;
3524:	
3525:		opts->lun0.lun = opts->common->luns[0];
3526:		opts->lun0.lun_id = 0;
3527:	
3528:		config_group_init_type_name(&opts->func_inst.group, "", &fsg_func_type);
3529:	
3530:		config_group_init_type_name(&opts->lun0.group, "lun.0", &fsg_lun_type);
3531:		configfs_add_default_group(&opts->lun0.group, &opts->func_inst.group);
3532:	
3533:		return &opts->func_inst;
3534:	
3535:	release_buffers:
3536:		fsg_common_free_buffers(opts->common);
3537:	release_common:
3538:		kfree(opts->common);
3539:	release_opts:
3540:		kfree(opts);
3541:		return ERR_PTR(rc);
3542:	}
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

144/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 23808
							output: 40
							thoughts: 140
						

Thoughts:
**Reflecting on Memory Management in `f_midi2`**

Okay, hold on a second... I was getting tripped up thinking about freeing `opts->lun0`, but then I realized it's part of the main `opts` structure, so that's handled implicitly. My focus needs to be on the dynamic allocation within `f_midi2`. Ah, yes, `kzalloc_obj()` is used for `ep_opts` and `block_opts`, which means they definitely need explicit freeing. The key is tracking their reference counts. If the count drops to zero, then they need to be freed. Now, I vaguely recall something about default groups. If they're added as default groups, their refcount will increase. Did `configfs_add_default_group` increment the refcount? Need to double-check that. Let me look at `configfs_add_default_group` to confirm. It's time to verify this and ensure everything is properly cleaned up.



145/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:include/linux/configfs.h Name:configfs_add_default_group]

Results:
map[SourceCode: 109:	static inline void configfs_add_default_group(struct config_group *new_group,
 110:			struct config_group *group)
 111:	{
 112:		list_add_tail(&new_group->group_entry, &group->default_groups);
 113:	}
 SourceFile:include/linux/configfs.h]

146/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 24315
							output: 35
							thoughts: 75
						

Thoughts:
**Analyzing ConfigFS Group Management**

Okay, so I'm focusing on how `configfs_add_default_group` works. It's becoming clear that this function *only* adds to the `default_groups` list. It doesn't appear to handle any refcounting itself. That's the key.

This means the reference count for those added groups will need to be managed elsewhere. The crucial point now is when and how the reference count might actually get incremented. My gut feeling is that it might happen during the population of the parent group within the configfs structure. The action I need to check is if `populate_groups`, the function called during this population, plays a role in managing that refcount.

I’m now going to dig into the `populate_groups` function, specifically within `fs/configfs/dir.c` to see how it handles things, including checking its role in reference counting.



147/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:populate_groups]

Results:
map[SourceCode: 734:	static int populate_groups(struct config_group *group,
 735:				   struct configfs_fragment *frag)
 736:	{
 737:		struct dentry *parent = group->cg_item.ci_dentry;
 738:		struct config_group *new_group;
 739:	
 740:		list_for_each_entry(new_group, &group->default_groups, group_entry) {
 741:			int ret = create_default_group(parent, new_group, frag);
 742:			if (ret)
 743:				return ret;
 744:		}
 745:		return 0;
 746:	}
 SourceFile:fs/configfs/dir.c]

148/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 24847
							output: 37
							thoughts: 11
						

Thoughts:
Okay, here's my interpretation of that thought process, assuming I'm deeply familiar with code and system design:

**Checking `create_default_group` Functionality**

Alright, the mental checklist begins. First, let's zero in on that `create_default_group` function. I need to quickly assess what it *should* be doing and whether it's doing it correctly. Is this the right spot to start debugging, reviewing, or extending a system? Am I looking at this function due to a bug report, a performance issue, or as part of a larger refactor?

My immediate thoughts are, what are the implicit contracts this function honors?

*   Does it handle error conditions gracefully?
*   What is the expected behavior if a default group already exists?
*   How is this group defined?
*   Where is this defined group used?
*   Are there race conditions to consider during concurrent access?
*   Are there any security implications of default group creation and assignment?

I'm thinking about the function's dependencies – what other functions or data structures does it rely on? Are those dependencies well-defined, and is there a possibility for a cascading effect of errors?

I'm not going to immediately jump into the code. Instead, I'll probably start with a quick mental walkthrough, tracing the expected execution flow and edge cases to ensure the function aligns with the overall system design. From there, I'll determine if I need to dive into the code directly, look at unit tests, or examine related documentation.



149/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:create_default_group]

Results:
map[SourceCode: 695:	/*
 696:	 * This fakes mkdir(2) on a default_groups[] entry.  It
 697:	 * creates a dentry, attachs it, and then does fixup
 698:	 * on the sd->s_type.
 699:	 *
 700:	 * We could, perhaps, tweak our parent's ->mkdir for a minute and
 701:	 * try using vfs_mkdir.  Just a thought.
 702:	 */
 703:	static int create_default_group(struct dentry *parent,
 704:					struct config_group *group,
 705:					struct configfs_fragment *frag)
 706:	{
 707:		int ret;
 708:		struct configfs_dirent *sd;
 709:		/* We trust the caller holds a reference to parent */
 710:		struct dentry *child;
 711:	
 712:		if (!group->cg_item.ci_name)
 713:			group->cg_item.ci_name = group->cg_item.ci_namebuf;
 714:	
 715:		ret = -ENOMEM;
 716:		child = d_alloc_name(parent, group->cg_item.ci_name);
 717:		if (child) {
 718:			d_add(child, NULL);
 719:	
 720:			ret = configfs_attach_group(&group->cg_item, child, frag);
 721:			if (!ret) {
 722:				sd = child->d_fsdata;
 723:				sd->s_type |= CONFIGFS_USET_DEFAULT;
 724:			} else {
 725:				BUG_ON(d_inode(child));
 726:				d_drop(child);
 727:			}
 728:			dput(child);
 729:		}
 730:	
 731:		return ret;
 732:	}
 SourceFile:fs/configfs/dir.c]

150/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 25803
							output: 38
							thoughts: 12
						

Thoughts:
Here's my take on those thoughts, tailored for an expert audience:

**Diving into `configfs_attach_group`**

Okay, time to dissect `configfs_attach_group`. I need to refresh my understanding of how this function fits into the overall configfs architecture, specifically when we're attaching a new group. My mental model needs a quick update. I'm immediately thinking about the implications for object lifecycle management within the filesystem. Is this where the permissions are enforced? How does this interact with the various attribute operations, and does it mean we need to re-evaluate the object based on its parent? Is the function handling reference counting correctly? A quick review of the relevant source code is definitely in order. I'll need to pay close attention to the error handling paths as well, especially regarding resource allocation and cleanup. I anticipate there might be some nuanced locking considerations around the attach process, and that's something I don't want to overlook. Let's get to it.



151/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_attach_group]

Results:
map[SourceCode: 891:	static int configfs_attach_group(struct config_item *item,
 892:					 struct dentry *dentry,
 893:					 struct configfs_fragment *frag)
 894:	{
 895:		int ret;
 896:		struct configfs_dirent *sd;
 897:	
 898:		ret = configfs_attach_item(item, dentry, frag);
 899:		if (!ret) {
 900:			sd = dentry->d_fsdata;
 901:			sd->s_type |= CONFIGFS_USET_DIR;
 902:	
 903:			/*
 904:			 * FYI, we're faking mkdir in populate_groups()
 905:			 * We must lock the group's inode to avoid races with the VFS
 906:			 * which can already hit the inode and try to add/remove entries
 907:			 * under it.
 908:			 *
 909:			 * We must also lock the inode to remove it safely in case of
 910:			 * error, as rmdir() would.
 911:			 */
 912:			inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD);
 913:			configfs_adjust_dir_dirent_depth_before_populate(sd);
 914:			ret = populate_groups(to_config_group(item), frag);
 915:			if (ret) {
 916:				configfs_detach_group(dentry);
 917:				d_inode(dentry)->i_flags |= S_DEAD;
 918:				dont_mount(dentry);
 919:			}
 920:			configfs_adjust_dir_dirent_depth_after_populate(sd);
 921:			inode_unlock(d_inode(dentry));
 922:			if (ret)
 923:				d_delete(dentry);
 924:		}
 925:	
 926:		return ret;
 927:	}
 SourceFile:fs/configfs/dir.c]

152/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 26653
							output: 38
							thoughts: 12
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Diving into `configfs_attach_item`**

Alright, time to dig into `configfs_attach_item`. Seems like a critical point, right? Understanding how items are attached is fundamental to grasping the whole ConfigFS architecture. I need to make sure I'm solid on the mechanics of this function. Let's see... what are the key data structures involved at this stage? Is it primarily about linking the filesystem inode and dentry, or are there more complex operations happening behind the scenes, like attribute initialization or permission checks? My intuition says it’s more than just a simple inode/dentry connection, especially given the flexibility ConfigFS offers. I need to refresh my memory on the interactions with the backing storage, if any, and the implications for attribute handling. This could be a good point to look at how different item types are handled differently. Let's start breaking down the code and see what nuances pop up.



153/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_attach_item]

Results:
map[SourceCode: 842:	/*
 843:	 * The goal is that configfs_attach_item() (and
 844:	 * configfs_attach_group()) can be called from either the VFS or this
 845:	 * module.  That is, they assume that the items have been created,
 846:	 * the dentry allocated, and the dcache is all ready to go.
 847:	 *
 848:	 * If they fail, they must clean up after themselves as if they
 849:	 * had never been called.  The caller (VFS or local function) will
 850:	 * handle cleaning up the dcache bits.
 851:	 *
 852:	 * configfs_detach_group() and configfs_detach_item() behave similarly on
 853:	 * the way out.  They assume that the proper semaphores are held, they
 854:	 * clean up the configfs items, and they expect their callers will
 855:	 * handle the dcache bits.
 856:	 */
 857:	static int configfs_attach_item(struct config_item *item,
 858:					struct dentry *dentry,
 859:					struct configfs_fragment *frag)
 860:	{
 861:		int ret;
 862:	
 863:		ret = configfs_create_dir(item, dentry, frag);
 864:		if (!ret) {
 865:			ret = populate_attrs(item);
 866:			if (ret) {
 867:				/*
 868:				 * We are going to remove an inode and its dentry but
 869:				 * the VFS may already have hit and used them. Thus,
 870:				 * we must lock them as rmdir() would.
 871:				 */
 872:				inode_lock(d_inode(dentry));
 873:				configfs_detach_item(dentry);
 874:				d_inode(dentry)->i_flags |= S_DEAD;
 875:				dont_mount(dentry);
 876:				inode_unlock(d_inode(dentry));
 877:				d_delete(dentry);
 878:			}
 879:		}
 880:	
 881:		return ret;
 882:	}
 SourceFile:fs/configfs/dir.c]

154/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 27577
							output: 38
							thoughts: 18
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented as if it were my own internal monologue:

**A Potential Data Race Alert!**

Alright, hang on a second. I'm just tracing through this `configfs` code, and something's pinging my radar. I'm seeing that `configfs_create_dir` function... and it's calling `config_item_get`. That little detail is sparking a concern in my mind.

Now, from what I know about this system, if `config_item_get` is being used to increase a reference count within the directory creation process, and if `configfs_create_dir` is not handling potential concurrent access correctly… then we might have a subtle, hard-to-reproduce, data race issue on our hands.

My initial thought is to look at how `config_item_get` and `configfs_create_dir` interact specifically: is the new directory properly guarded against concurrent destruction, or are we perhaps creating a window where another thread or process could free the item while we're in the middle of initialization or metadata setup?

I need to analyze the surrounding locking mechanisms within `configfs_create_dir` and the overall context of that `config_item_get` call very carefully. Are there adequate spinlocks, mutexes, or RCU guarantees in place to protect the data structure? This might be something to look out for. I'm going to dig a little deeper into this.



155/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_create_dir]

Results:
map[SourceCode: 293:	static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
 294:					struct configfs_fragment *frag)
 295:	{
 296:		int error;
 297:		umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
 298:		struct dentry *p = dentry->d_parent;
 299:		struct inode *p_inode = d_inode(p);
 300:		struct inode *inode;
 301:	
 302:		BUG_ON(!item);
 303:	
 304:		error = configfs_make_dirent(p->d_fsdata, dentry, item, mode,
 305:					     CONFIGFS_DIR | CONFIGFS_USET_CREATING,
 306:					     frag);
 307:		if (unlikely(error))
 308:			return error;
 309:	
 310:		configfs_set_dir_dirent_depth(p->d_fsdata, dentry->d_fsdata);
 311:		inode = configfs_create(dentry, mode);
 312:		if (IS_ERR(inode))
 313:			goto out_remove;
 314:	
 315:		inode->i_op = &configfs_dir_inode_operations;
 316:		inode->i_fop = &configfs_dir_operations;
 317:		/* directory inodes start off with i_nlink == 2 (for "." entry) */
 318:		inc_nlink(inode);
 319:		d_make_persistent(dentry, inode);
 320:		inc_nlink(p_inode);
 321:		inode_set_mtime_to_ts(p_inode, inode_set_ctime_current(p_inode));
 322:		item->ci_dentry = dentry;
 323:		return 0;
 324:	
 325:	out_remove:
 326:		configfs_put(dentry->d_fsdata);
 327:		configfs_remove_dirent(dentry);
 328:		return PTR_ERR(inode);
 329:	}
 SourceFile:fs/configfs/dir.c]

156/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 28605
							output: 39
							thoughts: 20
						

Thoughts:
Here's my attempt at summarizing that thought process, tailored for an expert audience:

**Digging into the configfs Internals**

Okay, hold on a second. I'm following the flow here, tracing this `configfs_make_dirent` function, and it seems... hang on... am I reading this right? It's calling `config_item_get` inside? That's... interesting. Why would we be incrementing the reference count of the configfs item *within* the dirent creation function? Typically you’d expect the item to be "gotten" (and thus ref-counted) at a higher level, like within the actual VFS operations that use the dirent. This feels like it might introduce an unexpected order-of-operations dependency or a potential refcount imbalance if a different part of the code needs to use this dirent. I need to understand this call flow and the lifetime guarantees of these dirents much better now. This could have some important implications for concurrent access and resource management within configfs. Time to delve deeper...



157/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_make_dirent]

Results:
map[SourceCode: 253:	int configfs_make_dirent(struct configfs_dirent * parent_sd,
 254:				 struct dentry * dentry, void * element,
 255:				 umode_t mode, int type, struct configfs_fragment *frag)
 256:	{
 257:		struct configfs_dirent * sd;
 258:	
 259:		sd = configfs_new_dirent(parent_sd, element, type, frag);
 260:		if (IS_ERR(sd))
 261:			return PTR_ERR(sd);
 262:	
 263:		sd->s_mode = mode;
 264:		sd->s_dentry = dentry;
 265:		if (dentry)
 266:			dentry->d_fsdata = configfs_get(sd);
 267:	
 268:		return 0;
 269:	}
 SourceFile:fs/configfs/dir.c]

158/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 29175
							output: 39
							thoughts: 13
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience and written in the first person:

**Diving into `configfs_new_dirent`**

Okay, so we're looking at `configfs_new_dirent`. Time to refresh my mental model of that function. I need to quickly recall how this piece slots into the broader ConfigFS ecosystem. What are the key data structures being manipulated here? It's where the magic of creating new directory entries happens, so I'm expecting to see calls related to inode allocation, possibly `dentry` creation, and definitely some attribute setting for the new entry. Let's see if there are any specific locking considerations in this function, especially if it deals with concurrent accesses to the ConfigFS filesystem. I want to make sure the implementation handles the race conditions in the file system.



159/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_new_dirent]

Results:
map[SourceCode: 184:	/*
 185:	 * Allocates a new configfs_dirent and links it to the parent configfs_dirent
 186:	 */
 187:	static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *parent_sd,
 188:							   void *element, int type,
 189:							   struct configfs_fragment *frag)
 190:	{
 191:		struct configfs_dirent * sd;
 192:	
 193:		sd = kmem_cache_zalloc(configfs_dir_cachep, GFP_KERNEL);
 194:		if (!sd)
 195:			return ERR_PTR(-ENOMEM);
 196:	
 197:		atomic_set(&sd->s_count, 1);
 198:		INIT_LIST_HEAD(&sd->s_children);
 199:		sd->s_element = element;
 200:		sd->s_type = type;
 201:		configfs_init_dirent_depth(sd);
 202:		spin_lock(&configfs_dirent_lock);
 203:		if (parent_sd->s_type & CONFIGFS_USET_DROPPING) {
 204:			spin_unlock(&configfs_dirent_lock);
 205:			kmem_cache_free(configfs_dir_cachep, sd);
 206:			return ERR_PTR(-ENOENT);
 207:		}
 208:		sd->s_frag = get_fragment(frag);
 209:	
 210:		/*
 211:		 * configfs_lookup scans only for unpinned items. s_children is
 212:		 * partitioned so that configfs_lookup can bail out early.
 213:		 * CONFIGFS_PINNED and CONFIGFS_NOT_PINNED are not symmetrical.  readdir
 214:		 * cursors still need to be inserted at the front of the list.
 215:		 */
 216:		if (sd->s_type & CONFIGFS_PINNED)
 217:			list_add_tail(&sd->s_sibling, &parent_sd->s_children);
 218:		else
 219:			list_add(&sd->s_sibling, &parent_sd->s_children);
 220:		spin_unlock(&configfs_dirent_lock);
 221:	
 222:		return sd;
 223:	}
 SourceFile:fs/configfs/dir.c]

160/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 30103
							output: 36
							thoughts: 47
						

Thoughts:
Okay, here's my take on those thoughts, framed as my own mental processing:

**Digging into the ConfigFS Creation Process**

Alright, let's trace this directory creation. So, `configfs_attach_group` uses `configfs_attach_item`, and that's the function that actually creates the directory entry. Makes sense. Now I'm wondering, where is this `config_item_get` function called? I'm trying to understand the lifecycle of these config items. Knowing that will give me context as to *why* they are being created. Let me jump over to the `configfs_mkdir` implementation. That seems like a logical spot to find clues, since `mkdir` is fundamentally about creating directories. I bet I'll find something there that will help me understand the relationship.



161/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_mkdir]

Results:
map[SourceCode:1289:	static struct dentry *configfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
1290:					     struct dentry *dentry, umode_t mode)
1291:	{
1292:		int ret = 0;
1293:		int module_got = 0;
1294:		struct config_group *group = NULL;
1295:		struct config_item *item = NULL;
1296:		struct config_item *parent_item;
1297:		struct configfs_subsystem *subsys;
1298:		struct configfs_dirent *sd;
1299:		const struct config_item_type *type;
1300:		struct module *subsys_owner = NULL, *new_item_owner = NULL;
1301:		struct configfs_fragment *frag;
1302:		struct name_snapshot n;
1303:		const char *name;
1304:	
1305:		take_dentry_name_snapshot(&n, dentry);
1306:		name = n.name.name;
1307:	
1308:		sd = dentry->d_parent->d_fsdata;
1309:	
1310:		/*
1311:		 * Fake invisibility if dir belongs to a group/default groups hierarchy
1312:		 * being attached
1313:		 */
1314:		if (!configfs_dirent_is_ready(sd)) {
1315:			ret = -ENOENT;
1316:			goto out;
1317:		}
1318:	
1319:		if (!(sd->s_type & CONFIGFS_USET_DIR)) {
1320:			ret = -EPERM;
1321:			goto out;
1322:		}
1323:	
1324:		frag = new_fragment();
1325:		if (!frag) {
1326:			ret = -ENOMEM;
1327:			goto out;
1328:		}
1329:	
1330:		/* Get a working ref for the duration of this function */
1331:		parent_item = configfs_get_config_item(dentry->d_parent);
1332:		type = parent_item->ci_type;
1333:		subsys = to_config_group(parent_item)->cg_subsys;
1334:		BUG_ON(!subsys);
1335:	
1336:		if (!type || !type->ct_group_ops ||
1337:		    (!type->ct_group_ops->make_group &&
1338:		     !type->ct_group_ops->make_item)) {
1339:			ret = -EPERM;  /* Lack-of-mkdir returns -EPERM */
1340:			goto out_put;
1341:		}
1342:	
1343:		/*
1344:		 * The subsystem may belong to a different module than the item
1345:		 * being created.  We don't want to safely pin the new item but
1346:		 * fail to pin the subsystem it sits under.
1347:		 */
1348:		if (!subsys->su_group.cg_item.ci_type) {
1349:			ret = -EINVAL;
1350:			goto out_put;
1351:		}
1352:		subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
1353:		if (!try_module_get(subsys_owner)) {
1354:			ret = -EINVAL;
1355:			goto out_put;
1356:		}
1357:	
1358:		mutex_lock(&subsys->su_mutex);
1359:		if (type->ct_group_ops->make_group) {
1360:			group = type->ct_group_ops->make_group(to_config_group(parent_item), name);
1361:			if (!group)
1362:				group = ERR_PTR(-ENOMEM);
1363:			if (!IS_ERR(group)) {
1364:				link_group(to_config_group(parent_item), group);
1365:				item = &group->cg_item;
1366:			} else
1367:				ret = PTR_ERR(group);
1368:		} else {
1369:			item = type->ct_group_ops->make_item(to_config_group(parent_item), name);
1370:			if (!item)
1371:				item = ERR_PTR(-ENOMEM);
1372:			if (!IS_ERR(item))
1373:				link_obj(parent_item, item);
1374:			else
1375:				ret = PTR_ERR(item);
1376:		}
1377:		mutex_unlock(&subsys->su_mutex);
1378:	
1379:		if (ret) {
1380:			/*
1381:			 * If ret != 0, then link_obj() was never called.
1382:			 * There are no extra references to clean up.
1383:			 */
1384:			goto out_subsys_put;
1385:		}
1386:	
1387:		/*
1388:		 * link_obj() has been called (via link_group() for groups).
1389:		 * From here on out, errors must clean that up.
1390:		 */
1391:	
1392:		type = item->ci_type;
1393:		if (!type) {
1394:			ret = -EINVAL;
1395:			goto out_unlink;
1396:		}
1397:	
1398:		new_item_owner = type->ct_owner;
1399:		if (!try_module_get(new_item_owner)) {
1400:			ret = -EINVAL;
1401:			goto out_unlink;
1402:		}
1403:	
1404:		/*
1405:		 * I hate doing it this way, but if there is
1406:		 * an error,  module_put() probably should
1407:		 * happen after any cleanup.
1408:		 */
1409:		module_got = 1;
1410:	
1411:		/*
1412:		 * Make racing rmdir() fail if it did not tag parent with
1413:		 * CONFIGFS_USET_DROPPING
1414:		 * Note: if CONFIGFS_USET_DROPPING is already set, attach_group() will
1415:		 * fail and let rmdir() terminate correctly
1416:		 */
1417:		spin_lock(&configfs_dirent_lock);
1418:		/* This will make configfs_detach_prep() fail */
1419:		sd->s_type |= CONFIGFS_USET_IN_MKDIR;
1420:		spin_unlock(&configfs_dirent_lock);
1421:	
1422:		if (group)
1423:			ret = configfs_attach_group(item, dentry, frag);
1424:		else
1425:			ret = configfs_attach_item(item, dentry, frag);
1426:	
1427:		spin_lock(&configfs_dirent_lock);
1428:		sd->s_type &= ~CONFIGFS_USET_IN_MKDIR;
1429:		if (!ret)
1430:			configfs_dir_set_ready(dentry->d_fsdata);
1431:		spin_unlock(&configfs_dirent_lock);
1432:	
1433:	out_unlink:
1434:		if (ret) {
1435:			/* Tear down everything we built up */
1436:			mutex_lock(&subsys->su_mutex);
1437:	
1438:			client_disconnect_notify(parent_item, item);
1439:			if (group)
1440:				unlink_group(group);
1441:			else
1442:				unlink_obj(item);
1443:			client_drop_item(parent_item, item);
1444:	
1445:			mutex_unlock(&subsys->su_mutex);
1446:	
1447:			if (module_got)
1448:				module_put(new_item_owner);
1449:		}
1450:	
1451:	out_subsys_put:
1452:		if (ret)
1453:			module_put(subsys_owner);
1454:	
1455:	out_put:
1456:		/*
1457:		 * link_obj()/link_group() took a reference from child->parent,
1458:		 * so the parent is safely pinned.  We can drop our working
1459:		 * reference.
1460:		 */
1461:		config_item_put(parent_item);
1462:		put_fragment(frag);
1463:	
1464:	out:
1465:		release_dentry_name_snapshot(&n);
1466:		return ERR_PTR(ret);
1467:	}
 SourceFile:fs/configfs/dir.c]

162/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 32951
							output: 37
							thoughts: 244
						

Thoughts:
**Refcount Confusion in ConfigFS Group Creation**

Okay, so I'm tracing this `configfs_mkdir` call, and it's leading me down a rabbit hole. It calls `configfs_attach_group`, which then calls `populate_groups`, and that function calls `create_default_group`. The kicker? `create_default_group` *also* calls `configfs_attach_group`! This smells like a recursive loop waiting to happen, but that's not my main concern right now.

My immediate question is: where is the refcount being handled? I need to ensure proper object lifecycle management. `configfs_attach_group` calls `configfs_attach_item`, which calls a series of functions that eventually calls `configfs_new_dirent`. Then I can see that `configfs_new_dirent` sets `sd->s_count` to 1, but I'm looking for the kref.

I went back and checked `configfs_attach_item` to see if that function was incrementing `item->ci_kref`. No such luck, and `configfs_create_dir` doesn't seem to be doing it either. So, I have to find where `item->ci_kref` is incremented.

Then I realized, `configfs_mkdir` actually calls `make_group` or `make_item`, and these functions return the items with an initial refcount of 1, so the new object created from `configfs_mkdir` function call will already have a refcount of one.

However, default groups are handled differently. They are created with an existing `group` object that is passed to `create_default_group`. This seems like a potential issue, so I'm going to re-examine that function again.



163/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:create_default_group]

Results:
map[SourceCode: 695:	/*
 696:	 * This fakes mkdir(2) on a default_groups[] entry.  It
 697:	 * creates a dentry, attachs it, and then does fixup
 698:	 * on the sd->s_type.
 699:	 *
 700:	 * We could, perhaps, tweak our parent's ->mkdir for a minute and
 701:	 * try using vfs_mkdir.  Just a thought.
 702:	 */
 703:	static int create_default_group(struct dentry *parent,
 704:					struct config_group *group,
 705:					struct configfs_fragment *frag)
 706:	{
 707:		int ret;
 708:		struct configfs_dirent *sd;
 709:		/* We trust the caller holds a reference to parent */
 710:		struct dentry *child;
 711:	
 712:		if (!group->cg_item.ci_name)
 713:			group->cg_item.ci_name = group->cg_item.ci_namebuf;
 714:	
 715:		ret = -ENOMEM;
 716:		child = d_alloc_name(parent, group->cg_item.ci_name);
 717:		if (child) {
 718:			d_add(child, NULL);
 719:	
 720:			ret = configfs_attach_group(&group->cg_item, child, frag);
 721:			if (!ret) {
 722:				sd = child->d_fsdata;
 723:				sd->s_type |= CONFIGFS_USET_DEFAULT;
 724:			} else {
 725:				BUG_ON(d_inode(child));
 726:				d_drop(child);
 727:			}
 728:			dput(child);
 729:		}
 730:	
 731:		return ret;
 732:	}
 SourceFile:fs/configfs/dir.c]

164/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 34203
							output: 35
							thoughts: 99
						

Thoughts:
**Analyzing the Data Structure Creation Process**

Okay, so I'm tracing the data structure creation flow here, specifically within the ConfigFS framework. The initial assumption I had was that `create_default_group` directly invokes `config_item_get`, but that doesn't seem to be the case. I need to rethink the path it takes.

Now, `configfs_attach_group` seems like the more likely entry point. This function calls `configfs_attach_item`, which itself calls `configfs_create_dir`. This then leads to `configfs_make_dirent`, which is interesting. It's creating directory entries, which is a key part of ConfigFS's behavior.

Hold on, I see a possible connection through `configfs_attach_item` to `populate_attrs`. It seems there's a chance that `populate_attrs` *might* call `config_item_get`. That would make more sense in the overall architecture. I need to confirm this. The details around attribute population is critical to understanding how the data is actually accessed.

So, let's dive into the implementation of `populate_attrs` to understand this process fully. Let's see if that's where the critical linkage exists.



165/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:populate_attrs]

Results:
map[SourceCode: 621:	static int populate_attrs(struct config_item *item)
 622:	{
 623:		const struct config_item_type *t = item->ci_type;
 624:		const struct configfs_group_operations *ops;
 625:		struct configfs_attribute *attr;
 626:		struct configfs_bin_attribute *bin_attr;
 627:		int error = 0;
 628:		int i;
 629:	
 630:		if (!t)
 631:			return -EINVAL;
 632:	
 633:		ops = t->ct_group_ops;
 634:	
 635:		if (t->ct_attrs) {
 636:			for (i = 0; (attr = t->ct_attrs[i]) != NULL; i++) {
 637:				if (ops && ops->is_visible && !ops->is_visible(item, attr, i))
 638:					continue;
 639:	
 640:				error = configfs_create_file(item, attr);
 641:				if (error)
 642:					return error;
 643:			}
 644:		}
 645:		if (t->ct_bin_attrs) {
 646:			for (i = 0; (bin_attr = t->ct_bin_attrs[i]) != NULL; i++) {
 647:				if (ops && ops->is_bin_visible && !ops->is_bin_visible(item, bin_attr, i))
 648:					continue;
 649:	
 650:				error = configfs_create_bin_file(item, bin_attr);
 651:				if (error)
 652:					return error;
 653:			}
 654:		}
 655:	
 656:		return 0;
 657:	}
 SourceFile:fs/configfs/dir.c]

166/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 35164
							output: 37
							thoughts: 28
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Investigating Default Group Configuration in configfs**

Alright, hang on a second. I'm trying to trace the lifecycle of these default group configurations, and I've hit a bit of a snag. I was following the trail, and now I've lost the specific call to `config_item_get` that should be happening for default groups. I need to figure out where that reference count increase occurs.

Let's see... since we're dealing with default group removal, it's highly likely that the relevant code will be in `configfs_rmdir`. This is where the cleanup process for a directory in configfs would be triggered, including the default group configuration. That's the most logical place to start digging. Time to dive into that function and see what it reveals about the reference counting for those default settings. I bet the crucial detail about the reference counting of the config items associated with the default group removal must be handled during the cleanup of the directory tree.



167/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_rmdir]

Results:
map[SourceCode:1469:	static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1470:	{
1471:		struct config_item *parent_item;
1472:		struct config_item *item;
1473:		struct configfs_subsystem *subsys;
1474:		struct configfs_dirent *sd;
1475:		struct configfs_fragment *frag;
1476:		struct module *subsys_owner = NULL, *dead_item_owner = NULL;
1477:		int ret;
1478:	
1479:		sd = dentry->d_fsdata;
1480:		if (sd->s_type & CONFIGFS_USET_DEFAULT)
1481:			return -EPERM;
1482:	
1483:		/* Get a working ref until we have the child */
1484:		parent_item = configfs_get_config_item(dentry->d_parent);
1485:		subsys = to_config_group(parent_item)->cg_subsys;
1486:		BUG_ON(!subsys);
1487:	
1488:		if (!parent_item->ci_type) {
1489:			config_item_put(parent_item);
1490:			return -EINVAL;
1491:		}
1492:	
1493:		/* configfs_mkdir() shouldn't have allowed this */
1494:		BUG_ON(!subsys->su_group.cg_item.ci_type);
1495:		subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
1496:	
1497:		/*
1498:		 * Ensure that no racing symlink() will make detach_prep() fail while
1499:		 * the new link is temporarily attached
1500:		 */
1501:		do {
1502:			struct dentry *wait;
1503:	
1504:			mutex_lock(&configfs_symlink_mutex);
1505:			spin_lock(&configfs_dirent_lock);
1506:			/*
1507:			 * Here's where we check for dependents.  We're protected by
1508:			 * configfs_dirent_lock.
1509:			 * If no dependent, atomically tag the item as dropping.
1510:			 */
1511:			ret = sd->s_dependent_count ? -EBUSY : 0;
1512:			if (!ret) {
1513:				ret = configfs_detach_prep(sd, &wait);
1514:				if (ret)
1515:					configfs_detach_rollback(sd);
1516:			}
1517:			spin_unlock(&configfs_dirent_lock);
1518:			mutex_unlock(&configfs_symlink_mutex);
1519:	
1520:			if (ret) {
1521:				if (ret != -EAGAIN) {
1522:					config_item_put(parent_item);
1523:					return ret;
1524:				}
1525:	
1526:				/* Wait until the racing operation terminates */
1527:				inode_lock(d_inode(wait));
1528:				inode_unlock(d_inode(wait));
1529:				dput(wait);
1530:			}
1531:		} while (ret == -EAGAIN);
1532:	
1533:		frag = sd->s_frag;
1534:		if (down_write_killable(&frag->frag_sem)) {
1535:			spin_lock(&configfs_dirent_lock);
1536:			configfs_detach_rollback(sd);
1537:			spin_unlock(&configfs_dirent_lock);
1538:			config_item_put(parent_item);
1539:			return -EINTR;
1540:		}
1541:		frag->frag_dead = true;
1542:		up_write(&frag->frag_sem);
1543:	
1544:		/* Get a working ref for the duration of this function */
1545:		item = configfs_get_config_item(dentry);
1546:	
1547:		/* Drop reference from above, item already holds one. */
1548:		config_item_put(parent_item);
1549:	
1550:		if (item->ci_type)
1551:			dead_item_owner = item->ci_type->ct_owner;
1552:	
1553:		if (sd->s_type & CONFIGFS_USET_DIR) {
1554:			configfs_detach_group(dentry);
1555:	
1556:			mutex_lock(&subsys->su_mutex);
1557:			client_disconnect_notify(parent_item, item);
1558:			unlink_group(to_config_group(item));
1559:		} else {
1560:			configfs_detach_item(dentry);
1561:	
1562:			mutex_lock(&subsys->su_mutex);
1563:			client_disconnect_notify(parent_item, item);
1564:			unlink_obj(item);
1565:		}
1566:	
1567:		client_drop_item(parent_item, item);
1568:		mutex_unlock(&subsys->su_mutex);
1569:	
1570:		/* Drop our reference from above */
1571:		config_item_put(item);
1572:	
1573:		module_put(dead_item_owner);
1574:		module_put(subsys_owner);
1575:	
1576:		return 0;
1577:	}
 SourceFile:fs/configfs/dir.c]

168/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 37080
							output: 35
							thoughts: 45
						

Thoughts:
Okay, let's see...

**Deconstructing the ConfigFS Removal Process**

Right, so I'm tracing the removal of a directory in `configfs`. It looks like `configfs_rmdir` is the starting point. That function calls `configfs_detach_group`, which is interesting. And *that* in turn calls `configfs_detach_item` and then, crucially, `detach_groups`. I need to understand how the system detaches these groups, as that likely affects how all the items are removed. Let's delve into that `detach_groups` function. It's the lynchpin, it would seem, of the entire removal sequence, so that's where my focus needs to be now.



169/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:detach_groups]

Results:
map[SourceCode: 664:	static void detach_groups(struct dentry *dentry)
 665:	{
 666:		struct dentry *child;
 667:		struct configfs_dirent *parent_sd;
 668:		struct configfs_dirent *sd, *next;
 669:	
 670:		parent_sd = dentry->d_fsdata;
 671:		spin_lock(&configfs_dirent_lock);
 672:		for (sd = next_dirent(parent_sd, NULL); sd; sd = next) {
 673:			next = next_dirent(parent_sd, sd);
 674:			if (!(sd->s_type & CONFIGFS_USET_DEFAULT))
 675:				continue;
 676:	
 677:			child = dget(sd->s_dentry);
 678:			spin_unlock(&configfs_dirent_lock);
 679:	
 680:			inode_lock(d_inode(child));
 681:	
 682:			configfs_detach_group(child);
 683:			d_inode(child)->i_flags |= S_DEAD;
 684:			dont_mount(child);
 685:	
 686:			inode_unlock(d_inode(child));
 687:	
 688:			d_delete(child);
 689:			dput(child);
 690:			spin_lock(&configfs_dirent_lock);
 691:		}
 692:		spin_unlock(&configfs_dirent_lock);
 693:	}
 SourceFile:fs/configfs/dir.c]

170/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 37788
							output: 38
							thoughts: 52
						

Thoughts:
Here's my summary, as the expert:

**Tracing the ConfigFS Detachment Process**

Okay, hold on a second. I need to refresh my understanding of how this detachment is handled within ConfigFS. My mental model is telling me that `detach_groups` is going to call `configfs_detach_group` for the default group. I better confirm that assumption. Yep, that's what's happening. Alright, `configfs_detach_group` then calls `configfs_detach_item`. Interesting. I should probably quickly check the implementation of `configfs_detach_item` to fully grasp the low-level details of that operation before I dig any deeper. No point in wasting time with the high level if I'm missing some small detail.



171/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_detach_item]

Results:
map[SourceCode: 835:	/* Caller holds the mutex of the item's inode */
 836:	static void configfs_detach_item(struct dentry *dentry)
 837:	{
 838:		detach_attrs(dentry);
 839:		configfs_remove_dir(dentry);
 840:	}
 SourceFile:fs/configfs/dir.c]

172/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 38161
							output: 38
							thoughts: 19
						

Thoughts:
Here's my attempt at summarizing that thought process, tailored for an expert audience:

**Kernel Subsystem Debugging - A ConfigFS Question**

Okay, so I'm digging into this ConfigFS code, trying to understand the lifecycle of these items. I was just looking at `configfs_remove_dir`, and something jumped out at me. Wait a second... `configfs_remove_dir`? That function, which is supposed to be *removing* a directory in the ConfigFS hierarchy... is it actually calling `config_item_put`? That's not what I initially expected. I usually think about directory removal as a filesystem-level operation like a kind of rmdir, not the final release of the resource. `config_item_put` seems to handle reference counting and resource deallocation. I need to understand this better. Is this where the actual cleanup of the ConfigFS item happens? Or is `configfs_remove_dir` handling a higher level of operations? I really need to check the call chain and double-check how these functions interact.



173/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_remove_dir]

Results:
map[SourceCode: 410:	static void configfs_remove_dir(struct dentry *d)
 411:	{
 412:		struct dentry * parent = dget(d->d_parent);
 413:	
 414:		configfs_remove_dirent(d);
 415:	
 416:		if (d_really_is_positive(d)) {
 417:			if (unlikely(simple_rmdir(d_inode(parent), d)))
 418:				pr_warn("remove_dir (%pd): attributes remain", d);
 419:		}
 420:	
 421:		pr_debug(" o %pd removing done (%d)\n", d, d_count(d));
 422:	
 423:		dput(parent);
 424:	}
 SourceFile:fs/configfs/dir.c]

174/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 38696
							output: 39
							thoughts: 20
						

Thoughts:
Here's my take on those thoughts:

**A Quick Cross-Check**

Okay, so I'm digging into this `configfs_remove_dirent` function and something's pinging my radar. Hold on... it *calls* `config_item_put`? That's a key interaction. I need to make sure I understand the full lifecycle here. Is this an intentional cleanup step, or potentially a hidden resource leak point? `config_item_put` is how we decrement the reference count, right? I need to quickly verify the intended semantics and ensure there are no potential race conditions or double-frees related to this put. I should trace the context and other call paths that lead to an item put. I'll need to double check the reference counting strategy that's in play here. Is the timing correct? Let's verify and be certain.



175/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_remove_dirent]

Results:
map[SourceCode: 271:	static void configfs_remove_dirent(struct dentry *dentry)
 272:	{
 273:		struct configfs_dirent *sd = dentry->d_fsdata;
 274:	
 275:		if (!sd)
 276:			return;
 277:		spin_lock(&configfs_dirent_lock);
 278:		list_del_init(&sd->s_sibling);
 279:		spin_unlock(&configfs_dirent_lock);
 280:		configfs_put(sd);
 281:	}
 SourceFile:fs/configfs/dir.c]

176/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 39133
							output: 36
							thoughts: 17
						

Thoughts:
Here's my attempt at summarizing that thought process, tailored for an expert audience:

**Digging into the configfs Internals**

Okay, hold on a second. I'm tracing through the `configfs` code, and I just saw a call to `configfs_put`. My mental model of the reference counting in `configfs` had `configfs_put` as a direct release for the filesystem objects, but now I'm seeing it go down a level and call `config_item_put`. That's unexpected, and I need to check my understanding. It makes me question where the primary ownership lies and how the refcounting is actually implemented in this part of the kernel. Is `configfs` simply a higher-level interface that relies on lower-level `config_item` to be deallocated? I need to review the architecture documentation to confirm this, but right now I'm processing this newly surfaced detail.



177/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_put]

Results:
map[SourceCode: 152:	static inline void configfs_put(struct configfs_dirent * sd)
 153:	{
 154:		WARN_ON(!atomic_read(&sd->s_count));
 155:		if (atomic_dec_and_test(&sd->s_count))
 156:			release_configfs_dirent(sd);
 157:	}
 SourceFile:fs/configfs/configfs_internal.h]

178/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 39518
							output: 39
							thoughts: 13
						

Thoughts:
Here's a summary of my thought process, as requested:

**Checking `release_configfs_dirent`**

Okay, let's dive in. The task at hand is to understand and potentially work with the `release_configfs_dirent` function. My initial thought process is to establish its purpose within the broader scope of ConfigFS. What exactly is this function designed to do? My expert knowledge immediately leans towards the idea that it's handling the cleanup or relinquishing of a directory entry within the ConfigFS filesystem. Likely related to reference counting or memory management. I want to quickly verify my initial assumption. I'm already anticipating considerations around locking mechanisms if this is a critical cleanup function, and I'll keep this front of mind. I'll need to remember to check for any potential race conditions and the context in which this function is invoked. Is it called during unmount operations? Is it called when a ConfigFS object is destroyed? Understanding the calling context is paramount to understanding its implications for concurrency and overall system stability. I also need to ascertain what parameters it takes to be sure of its intent, and ensure that I know if these parameters are used. From there, I'll need to figure out what happens, such as if it frees memory, decrements reference counters, or updates other internal data structures. This is where the core logic of the function lies. I'll want to check if the implementation is optimized in any way, maybe using inline functions. And of course, I'll pay close attention to potential error handling and any return values, to understand if there's any important status information this function passes back up the call chain.



179/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:release_configfs_dirent]

Results:
map[SourceCode: 134:	static inline void release_configfs_dirent(struct configfs_dirent * sd)
 135:	{
 136:		if (!(sd->s_type & CONFIGFS_ROOT)) {
 137:			kfree(sd->s_iattr);
 138:			put_fragment(sd->s_frag);
 139:			kmem_cache_free(configfs_dir_cachep, sd);
 140:		}
 141:	}
 SourceFile:fs/configfs/configfs_internal.h]

180/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 40079
							output: 40
							thoughts: 129
						

Thoughts:
**Investigating the `config_item_put` Usage in ConfigFS Default Group Removal**

Okay, so I'm trying to wrap my head around the memory management in this `configfs` context. Specifically, I'm focusing on how default groups are handled. First, I need to figure out where `config_item_put` is being called, because that's crucial for releasing resources.

Right, I see that `configfs_rmdir` *does* call `config_item_put(item)` at the very end. That's for explicit `rmdir` operations. But that's not quite what I'm looking for regarding default groups.

Aha! `detach_groups` handles the detach operation for default groups, and it calls `configfs_detach_group`. But, and here's the catch, I don't see `config_item_put` being called directly within `detach_groups` after `configfs_detach_group`! This is where things get interesting.

So, if `detach_groups` doesn't call `config_item_put`, how in the world is the memory for the default group actually being freed? It's a fundamental question. This implies that there is a different process responsible for the memory deallocation.

I'd better check `configfs_remove_default_groups` now. That feels like the next logical place to look.



181/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_remove_default_groups]

Results:
map[SourceCode: 748:	void configfs_remove_default_groups(struct config_group *group)
 749:	{
 750:		struct config_group *g, *n;
 751:	
 752:		list_for_each_entry_safe(g, n, &group->default_groups, group_entry) {
 753:			list_del(&g->group_entry);
 754:			config_item_put(&g->cg_item);
 755:		}
 756:	}
 SourceFile:fs/configfs/dir.c]

182/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 40723
							output: 40
							thoughts: 59
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience:

**Default Group Handling in ConfigFS: A Quick Puzzle**

Right, so I'm digging into `configfs_remove_default_groups`. The first thing that pops out is that it's meticulously calling `config_item_put` for each default group. That's good, expected behavior for releasing a reference, but it immediately raises a question in my mind. Where are those initial references coming from? When exactly are we *getting* those references in the first place? It's the standard ref-counting dance.

Let me refresh my memory of the counterpart function. Let's trace that logic back to `configfs_add_default_group`. I'll need to go over the calling context there to confirm my understanding of the reference count management. I'm probably missing a subtlety about how the initial ref is acquired and when these groups are created, and `configfs_add_default_group` should explain this.



183/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:include/linux/configfs.h Name:configfs_add_default_group]

Results:
map[SourceCode: 109:	static inline void configfs_add_default_group(struct config_group *new_group,
 110:			struct config_group *group)
 111:	{
 112:		list_add_tail(&new_group->group_entry, &group->default_groups);
 113:	}
 SourceFile:include/linux/configfs.h]

184/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 41155
							output: 46
							thoughts: 236
						

Thoughts:
**Analyzing a Potential ConfigFS Leak**

Okay, so I'm digging into this `configfs` code, and something's bugging me. I was reviewing how the default group is handled, and I just realized something. `configfs_add_default_group` doesn't seem to increment the reference count of the config item. But, hold on a second... `config_group_init_type_name` *does* call `config_item_init_type_name`, and that function *does* set the refcount to 1! So, the default group is created with a refcount of 1 initially.

Now, when `configfs_remove_default_groups` is called, it correctly calls `config_item_put`, which should decrement the refcount to 0, and that's when the release function should be triggered, right? But if `configfs_remove_default_groups` *isn't* called... then that default group's refcount never gets dropped to zero, and that sounds like a classic leak!

Okay, let's step back a moment. I need to be sure. Let's look at `f_mass_storage.c` as a good example. I know that uses `configfs_add_default_group` for `lun.0`. But... it *doesn't* call `configfs_remove_default_groups`! So why isn't `lun.0` leaking? That doesn't make any sense. I'm going to have to check `fsg_free_inst` again very closely.



185/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_mass_storage.c Name:fsg_free_inst]

Results:
map[SourceCode:3485:	static void fsg_free_inst(struct usb_function_instance *fi)
3486:	{
3487:		struct fsg_opts *opts;
3488:	
3489:		opts = fsg_opts_from_func_inst(fi);
3490:		fsg_common_release(opts->common);
3491:		kfree(opts);
3492:	}
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

186/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 41935
							output: 46
							thoughts: 136
						

Thoughts:
**Memory Management Quandary**

Okay, so I'm looking at this code and I see `opts` being freed with `kfree(opts)`. Seems straightforward. But, hold on a second... `opts->lun0` is embedded directly within `opts`. Right, so `kfree(opts)` *should* also free `opts->lun0` automatically. That makes sense.

But what about the configfs item? Is it detached from opts? My concern is that if `configfs_remove_default_groups` isn't called, then `lun.0`'s refcount will never hit zero. And if that refcount never reaches zero, then its associated release function won't be called, which could lead to a leak or dangling pointer.

Hold on a second, does `lun.0` even *have* a release function? I'd better check the definition of `fsg_lun_type` to make absolutely sure. I need to understand what resources that lun is holding to see if this is actually a problem or if my fears are unfounded. Okay, let's look at `fsg_lun_type`.



187/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_mass_storage.c Name:fsg_lun_type]

Results:
map[SourceCode:3284:	static const struct config_item_type fsg_lun_type = {
3285:		.ct_item_ops	= &fsg_lun_item_ops,
3286:		.ct_attrs	= fsg_lun_attrs,
3287:		.ct_owner	= THIS_MODULE,
3288:	};
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

188/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 42493
							output: 48
							thoughts: 14
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience, and delivered as a first-person summary:

**Diving into `fsg_lun_item_ops`**

Alright, time to dig in. The immediate thing that jumps out is that I need to check `fsg_lun_item_ops`. This suggests we're likely dealing with something related to LUN operations within an FSG context. My gut tells me this is probably where the core logic for handling reads, writes, and potentially other interactions with the storage device resides, but it's not a certainty until I've seen the code. I need to understand how the file system interacts with, or uses, the functions this struct contains. Are we talking about direct I/O, buffered I/O, or something more complex like scatter-gather operations? What other structs and functions does it call? Knowing the specifics of the filesystem in question would also be useful context. I'll need to focus on what methods it provides, if there's any sophisticated locking employed and what data structures this `fsg_lun_item_ops` uses, especially in regards to its interaction with the underlying block device. I need to be thinking about potential performance bottlenecks, areas for optimization, and any possible race conditions or data consistency issues within this critical component. Let's see what we've got.



189/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_mass_storage.c Name:fsg_lun_item_ops]

Results:
map[SourceCode:3164:	static const struct configfs_item_operations fsg_lun_item_ops = {
3165:		.release		= fsg_lun_attr_release,
3166:	};
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

190/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 42937
							output: 48
							thoughts: 14
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Analyzing `fsg_lun_attr_release`**

Alright, let's dive into this `fsg_lun_attr_release` function. What are the key aspects I need to immediately consider? I need to analyze how this function interacts with the overall LUN attribute management system. Specifically, is this a critical point of potential resource leaks or race conditions? I need to quickly recall the data structures involved—is it interacting directly with the LUN object itself, or are there intermediary attribute containers? I will need to consider whether it's dealing with reference counting, and if so, how. Are there any known areas of concern with the underlying SCSI driver or file system interaction related to this release? I'm thinking about the implications of failure scenarios within this function. What error handling is in place, and are there potential scenarios where attributes might be partially released or not released at all, leading to system instability down the line? I need to look for any cross-thread interactions or locking primitives used within this function or those functions called by it. Lastly, I'll need to refresh my memory on any recent patches or changes that have touched this area, so I can ensure this function is still performing as intended.



191/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_mass_storage.c Name:fsg_lun_attr_release]

Results:
map[SourceCode:3156:	static void fsg_lun_attr_release(struct config_item *item)
3157:	{
3158:		struct fsg_lun_opts *lun_opts;
3159:	
3160:		lun_opts = to_fsg_lun_opts(item);
3161:		kfree(lun_opts);
3162:	}
 SourceFile:drivers/usb/gadget/function/f_mass_storage.c]

192/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 43410
							output: 44
							thoughts: 63
						

Thoughts:
**A Moment of Doubt, Then Clarity**

Okay, hold on a second! I'm seeing `fsg_lun_attr_release` being called, and it's calling `kfree(lun_opts)`! Alarm bells are starting to ring because I was pretty sure `lun.0` was embedded within `opts` structure, but if `opts` is freed, then so is `lun.0`, right? Wait... no, hold on. Is my understanding of the memory layout incorrect? Maybe `lun.0` *isn't* embedded within `opts`? Before I start down the wrong path, I need to verify how `fsg_opts` is structured to confirm my mental model. Time to double-check that part of the code.



193/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_mass_storage.c Name:fsg_opts]

Results:
map[SourceCode:  70:	struct fsg_opts {
  71:		struct fsg_common *common;
  72:		struct usb_function_instance func_inst;
  73:		struct fsg_lun_opts lun0;
  74:		struct config_group *default_groups[2];
  75:		bool no_configfs; /* for legacy gadgets */
  76:	
  77:		/*
  78:		 * Read/write access to configfs attributes is handled by configfs.
  79:		 *
  80:		 * This is to protect the data from concurrent access by read/write
  81:		 * and create symlink/remove symlink.
  82:		 */
  83:		struct mutex			lock;
  84:		int				refcnt;
  85:	};
 SourceFile:drivers/usb/gadget/function/f_mass_storage.h]

194/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 43923
							output: 48
							thoughts: 353
						

Thoughts:
**My Analysis of a Potential USB Gadget Driver Issue**

Okay, let's break this down. It looks like there's a problem with how `lun0` is being handled in the `fsg_opts` structure. I see that `lun0` is embedded directly within `fsg_opts`, which means when `fsg_lun_attr_release` is called, it might try to free an interior pointer. That's a red flag! The code calls `kfree(lun_opts)` where `lun_opts` is essentially pointing to `&opts->lun0`. I need to verify that `lun0` is even being released correctly.

My initial thought is that the leak is prevented because the refcount is never dropped to zero. However, `opts` is eventually freed in `fsg_free_inst` with `kfree(opts)`. So, the entire memory region gets freed. The memory itself isn't *leaked* in the traditional sense because it's being freed. But the refcount associated with the configfs item *is* being leaked. This is especially problematic because the configfs item remains in its list due to `configfs_remove_default_groups` never being called.

But if `opts` is being freed, then even the list head that contains the configfs item should be freed as well. Ah, since the *whole* `opts` is being freed, the list head gets freed as well. This makes me consider a potential problem: for `f_midi2`, `ep_opts`, and `block_opts` are dynamically allocated! Therefore, if their refcounts are leaked, the memory itself will be leaked! I need to investigate this further. I'll need to check if there are other commits in similar USB gadget functions that fix this exact issue of missing `configfs_remove_default_groups` calls. This could be a recurring pattern.



195/2 2026/07/30 14:17 tool git-log
0m Args:
map[CodeRegexp:configfs_remove_default_groups Count:20 PathPrefix:drivers/usb/ Since:10 years]

Results:
map[Output:]

196/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 44743
							output: 48
							thoughts: 101
						

Thoughts:
**USB Driver Deep Dive**

Okay, hold on a second. I was just reviewing the USB driver code and I noticed something odd. `configfs_remove_default_groups` seems to be completely unused within the entire `drivers/usb/` directory. That's a bit surprising, I figured it would be used at least somewhere, given its name and purpose.

Alright, let's back up a bit. If we're not removing default groups, are we at least *adding* any? I'll need to check the codebase to see where `configfs_add_default_group` *is* actually being used within the `drivers/usb/` directory.

Okay, after a quick grep, it looks like `f_mass_storage.c`, `f_midi2.c`, `uvc_configfs.c`, and even `configfs.c` are using the add function. Interesting. Let's delve into `uvc_configfs.c` first. It's the most likely one to have something significant. I want to understand *why* they need to add default groups in that specific module.



197/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/uvc_configfs.c Name:uvcg_config_create_group]

Results:
map[SourceCode: 156:	static int uvcg_config_create_group(struct config_group *parent,
 157:					    const struct uvcg_config_group_type *type)
 158:	{
 159:		struct config_group *group;
 160:	
 161:		group = kzalloc_obj(*group);
 162:		if (!group)
 163:			return -ENOMEM;
 164:	
 165:		config_group_init_type_name(group, type->name, &type->type);
 166:		configfs_add_default_group(group, parent);
 167:	
 168:		return uvcg_config_create_children(group, type);
 169:	}
 SourceFile:drivers/usb/gadget/function/uvc_configfs.c]

198/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 45383
							output: 48
							thoughts: 46
						

Thoughts:
Okay, here's my take on those thoughts, framed as my own mental processing:

**Memory Lane: Group Management in `uvcg_config`**

Alright, hang on a second. I'm looking at this `uvcg_config_create_group` function and it's starting to trigger some alarms. Specifically, I'm noting that it's dynamically allocating `group` and adding it to the default group. That's a classic setup for potential memory leaks, isn't it? My immediate question is: *how* is this allocated memory being freed? We can't just let it float around out there.

Let's dive deeper and track its lifecycle. My instinct tells me the cleanup will be in the `uvcg_config_remove_children` function. It's the logical place to look; this is where we'd expect the dismantling of the structure, and hopefully, the deallocation of any dynamically allocated memory associated with the created groups. Time to confirm my suspicion... let's see what's happening in there. I'm going to follow the logic and confirm my suspicions.



199/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/uvc_configfs.c Name:uvcg_config_remove_children]

Results:
map[SourceCode: 171:	static void uvcg_config_remove_children(struct config_group *group)
 172:	{
 173:		struct config_group *child, *n;
 174:	
 175:		list_for_each_entry_safe(child, n, &group->default_groups, group_entry) {
 176:			list_del(&child->group_entry);
 177:			uvcg_config_remove_children(child);
 178:			config_item_put(&child->cg_item);
 179:		}
 180:	}
 SourceFile:drivers/usb/gadget/function/uvc_configfs.c]

200/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 45914
							output: 40
							thoughts: 70
						

Thoughts:
Here's my summary, as the expert:

**Refactoring Opportunity Spotted: Simplifying Default Group Removal**

Okay, so I'm looking at this `uvcg_config_remove_children` function, and it's doing something that immediately rings a bell. It's manually looping through `default_groups`, removing each one, and then calling `config_item_put` on them. That whole dance… wait a minute! This is *exactly* the responsibility of `configfs_remove_default_groups`. I know I've seen that function before, so let me quickly double-check the implementation of `configfs_remove_default_groups` again. It has to be more efficient. This is likely a prime candidate for refactoring to reduce duplicated code.



201/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_remove_default_groups]

Results:
map[SourceCode: 748:	void configfs_remove_default_groups(struct config_group *group)
 749:	{
 750:		struct config_group *g, *n;
 751:	
 752:		list_for_each_entry_safe(g, n, &group->default_groups, group_entry) {
 753:			list_del(&g->group_entry);
 754:			config_item_put(&g->cg_item);
 755:		}
 756:	}
 SourceFile:fs/configfs/dir.c]

202/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 46360
							output: 39
							thoughts: 36
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Recursive Configuration Removal Confirmed - Quick Verification Required**

Yes! My initial hunch is correct, `uvcg_config_remove_children` indeed handles the recursive cleanup of the USB gadget configuration. That's precisely what I was hoping to see. It’s the standard approach, and it's nice to have a dedicated function for it.

However, I'm always cautious, especially with something so fundamental to device driver behavior. Before I commit to assuming this is *the* right function, a quick sanity check is warranted. Let's pull up `drivers/usb/gadget/configfs.c` for a rapid review. I want to confirm my understanding aligns with the actual implementation and make sure there are no obvious omissions or potential gotchas in its operation. Gotta confirm the fundamentals before building on this.



203/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/configfs.c Name:gadgets_drop]

Results:
map[SourceCode:2058:	static void gadgets_drop(struct config_group *group, struct config_item *item)
2059:	{
2060:		config_item_put(item);
2061:	}
 SourceFile:drivers/usb/gadget/configfs.c]

204/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 46716
							output: 39
							thoughts: 12
						

Thoughts:
Here's my take on those thoughts:

**Default Groups and the `gadgets_make` Function**

Okay, so I'm processing this... it just clicked. The `gadgets_make` function – the one we're using to instantiate these new gadget objects – it automatically adds default groups, doesn't it? I was so focused on the individual gadget creation process that I totally missed that subtle but crucial detail in its behavior. That's actually pretty convenient, now that I think about it. It handles a common initialization step without explicitly calling out each gadget's group affiliation in the creation step. That's pretty clever, actually; it keeps the instantiation code cleaner and reduces redundancy. I'll need to remember that the next time I'm digging into a similar system; this default group assignment is going to save me some lines, and some mental overhead.



205/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/configfs.c Name:gadgets_make]

Results:
map[SourceCode:1988:	static struct config_group *gadgets_make(
1989:			struct config_group *group,
1990:			const char *name)
1991:	{
1992:		struct gadget_info *gi;
1993:	
1994:		gi = kzalloc_obj(*gi);
1995:		if (!gi)
1996:			return ERR_PTR(-ENOMEM);
1997:	
1998:		config_group_init_type_name(&gi->group, name, &gadget_root_type);
1999:	
2000:		config_group_init_type_name(&gi->functions_group, "functions",
2001:				&functions_type);
2002:		configfs_add_default_group(&gi->functions_group, &gi->group);
2003:	
2004:		config_group_init_type_name(&gi->configs_group, "configs",
2005:				&config_desc_type);
2006:		configfs_add_default_group(&gi->configs_group, &gi->group);
2007:	
2008:		config_group_init_type_name(&gi->strings_group, "strings",
2009:				&gadget_language_strings_type);
2010:		configfs_add_default_group(&gi->strings_group, &gi->group);
2011:	
2012:		config_group_init_type_name(&gi->os_desc_group, "os_desc",
2013:				&os_desc_type);
2014:		configfs_add_default_group(&gi->os_desc_group, &gi->group);
2015:	
2016:		config_group_init_type_name(&gi->webusb_group, "webusb",
2017:				&webusb_type);
2018:		configfs_add_default_group(&gi->webusb_group, &gi->group);
2019:	
2020:		gi->composite.bind = configfs_do_nothing;
2021:		gi->composite.unbind = configfs_do_nothing;
2022:		gi->composite.suspend = NULL;
2023:		gi->composite.resume = NULL;
2024:		gi->composite.max_speed = USB_SPEED_SUPER_PLUS;
2025:	
2026:		spin_lock_init(&gi->spinlock);
2027:		mutex_init(&gi->lock);
2028:		INIT_LIST_HEAD(&gi->string_list);
2029:		INIT_LIST_HEAD(&gi->available_func);
2030:	
2031:		composite_init_dev(&gi->cdev);
2032:		gi->cdev.desc.bLength = USB_DT_DEVICE_SIZE;
2033:		gi->cdev.desc.bDescriptorType = USB_DT_DEVICE;
2034:		gi->cdev.desc.bcdDevice = cpu_to_le16(get_default_bcdDevice());
2035:	
2036:		gi->composite.gadget_driver = configfs_driver_template;
2037:	
2038:		gi->composite.gadget_driver.driver.name = kasprintf(GFP_KERNEL,
2039:								    "configfs-gadget.%s", name);
2040:		if (!gi->composite.gadget_driver.driver.name)
2041:			goto err;
2042:	
2043:		gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL);
2044:		gi->composite.name = gi->composite.gadget_driver.function;
2045:	
2046:		if (!gi->composite.gadget_driver.function)
2047:			goto out_free_driver_name;
2048:	
2049:		return &gi->group;
2050:	
2051:	out_free_driver_name:
2052:		kfree(gi->composite.gadget_driver.driver.name);
2053:	err:
2054:		kfree(gi);
2055:		return ERR_PTR(-ENOMEM);
2056:	}
 SourceFile:drivers/usb/gadget/configfs.c]

206/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 48127
							output: 43
							thoughts: 33
						

Thoughts:
Okay, let me think this through.

**Analyzing Group Management in `gadgets_make` and Related Functions**

Alright, so `gadgets_make` automatically adds these default groups, and that's the standard practice. The key question now becomes: Where and *how* are those groups subsequently removed, if at all? I need to understand the lifecycle of these default groups.

My immediate next step is to examine the `gadget_info_attr_release` function. That seems like the most logical place to start looking for the removal mechanism. It’s where information about the gadget would likely be released, which could include freeing up the default groups. I'll need to meticulously review the code within `gadget_info_attr_release` to see if there's group removal logic. I need to figure this out and confirm if there are any race conditions or unintended consequences.



207/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/configfs.c Name:gadget_info_attr_release]

Results:
map[SourceCode: 400:	static void gadget_info_attr_release(struct config_item *item)
 401:	{
 402:		struct gadget_info *gi = to_gadget_info(item);
 403:	
 404:		WARN_ON(!list_empty(&gi->cdev.configs));
 405:		WARN_ON(!list_empty(&gi->string_list));
 406:		WARN_ON(!list_empty(&gi->available_func));
 407:		kfree(gi->composite.gadget_driver.function);
 408:		kfree(gi->composite.gadget_driver.driver.name);
 409:		kfree(gi);
 410:	}
 SourceFile:drivers/usb/gadget/configfs.c]

208/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 48614
							output: 32
							thoughts: 71
						

Thoughts:
**Investigating a Potential Memory Leak**

Okay, hold on a second. I just realized something about how `gadget_info_attr_release` functions. It doesn't actually call `configfs_remove_default_groups`. That's unexpected. My immediate concern is that this could lead to a memory leak. I'm thinking, "Wait, is this code clean? Something isn't adding up".

So, the next question is, if `gadget_info_attr_release` isn't handling the cleanup of these default groups, where is it happening? Where is that function even being called? Is it possible that `configfs_remove_default_groups` is being invoked in another part of the codebase? I need to verify that; I want to be 100% sure. I'm going to revisit the implementation of `configfs_remove_default_groups` to confirm how its lifecycle is managed and figure out where the deallocation is actually happening.



209/2 2026/07/30 14:17 tool grepper
0m Error:
no matches

Args:
map[Expression:configfs_remove_default_groups PathPrefix:drivers/usb/]

Results:
map[Output:]

210/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 48941
							output: 32
							thoughts: 42
						

Thoughts:
Okay, let's see. My first thought is: **Hang on a minute, `configfs_remove_default_groups` isn't actually employed within the `drivers/usb/` directory at all! That's a red flag.**

I need to circle back and double-check my assumptions. Let's revisit `uvcg_config_remove_children` and give it a fresh look. I must have missed something or misunderstood a dependency in the initial pass. I'm going to carefully re-examine that function, paying close attention to any call sites or implications within the USB subsystem. I need to ensure my understanding of the removal process is accurate, given that the expected function isn't used where I thought.



211/2 2026/07/30 14:17 tool grepper
0m Args:
map[Expression:uvcg_config_remove_children PathPrefix:drivers/usb/]

Results:
map[Output:drivers/usb/gadget/function/uvc_configfs.c=156=static int uvcg_config_create_group(struct config_group *parent,
--
drivers/usb/gadget/function/uvc_configfs.c-170-
drivers/usb/gadget/function/uvc_configfs.c:171:static void uvcg_config_remove_children(struct config_group *group)
drivers/usb/gadget/function/uvc_configfs.c-172-{
--
drivers/usb/gadget/function/uvc_configfs.c-176-		list_del(&child->group_entry);
drivers/usb/gadget/function/uvc_configfs.c:177:		uvcg_config_remove_children(child);
drivers/usb/gadget/function/uvc_configfs.c-178-		config_item_put(&child->cg_item);
--
drivers/usb/gadget/function/uvc_configfs.c=3635=static void uvc_func_item_release(struct config_item *item)
--
drivers/usb/gadget/function/uvc_configfs.c-3638-
drivers/usb/gadget/function/uvc_configfs.c:3639:	uvcg_config_remove_children(to_config_group(item));
drivers/usb/gadget/function/uvc_configfs.c-3640-	usb_put_function_instance(&opts->func_inst);
]

212/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 49559
							output: 47
							thoughts: 709
						

Thoughts:
**Analyzing Potential Memory Leaks in ConfigFS Gadgets**

Okay, so I'm digging into this `uvc_configfs.c` code and something just clicked. It looks like `uvc_func_item_release` handles cleaning up children, but I need to consider what happens in `gadget_info_attr_release`. Specifically, if this release function *doesn't* remove default groups, is there a leak? Let's trace this...

Right, `gadgets_make` adds these default groups to `gi->group`, which is the root of the gadget. When the gadget gets removed with `rmdir`, `configfs_rmdir` gets called. This then calls `configfs_detach_group`, which in turn calls `detach_groups`. *This* is where it gets interesting...`detach_groups` iterates over `default_groups`, and calls `configfs_detach_group`, but critically, it *doesn't* call `config_item_put` on them!

So, if `detach_groups` doesn't do the refcount decrement, who does? I have to go back to `configfs_rmdir` and work through the logic. If it gets called on a group, it drops the refcount of the group itself. But what about the default groups that were added using `configfs_add_default_group` and are in the `default_groups` list?

Let me think... when `populate_groups` is called, it creates the dentries and increments the refcount, right? Actually, hold on. I remember `create_default_group` calling `configfs_attach_group`, which calls `configfs_attach_item`, which calls `configfs_create_dir`, which calls `configfs_make_dirent`, which calls `configfs_new_dirent`. None of these *actually* increment the refcount of the default group's `config_item`!

This is a problem. If `populate_groups` doesn't increment it, then the initial refcount of a default group is just 1, from `config_group_init_type_name`. Now, when the *parent* group is released, its `release` function gets called. If *that* function doesn't call `config_item_put` on the default groups, their refcount remains at 1, and we have a leak.

Now I'm looking at `gadget_info_attr_release` again. Does it call `config_item_put` on its default groups? Since `gi->functions_group`, `gi->configs_group`, etc., are *embedded* in `struct gadget_info`, then when `kfree(gi)` happens, their memory is freed! Since they are embedded, they don't need individual freeing. But that doesn't fix it, their refcount is still at 1. Wait, if the refcount is always 1, is that a problem? If the default group doesn't have dynamically allocated memory, it isn't a memory leak per se, but it's an issue with the refcounting. The problem is dynamic allocation! So it *would* be a leak *if* the default groups allocated memory, like `f_midi2` does with `ep_opts` and `block_opts` using `kzalloc_obj()`. If that refcount never drops to 0, that's definitely a leak! I should check the `f_midi2_alloc_inst` function.



213/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_alloc_inst]

Results:
map[SourceCode:2646:	/* gadget alloc_inst */
2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
2655:		if (!opts)
2656:			return ERR_PTR(-ENOMEM);
2657:	
2658:		mutex_init(&opts->lock);
2659:		opts->func_inst.free_func_inst = f_midi2_free_inst;
2660:		opts->info.process_ump = true;
2661:		opts->info.static_block = true;
2662:		opts->info.num_reqs = 32;
2663:		opts->info.req_buf_size = 512;
2664:	
2665:		/* create the default ep */
2666:		ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
2667:		if (ret) {
2668:			kfree(opts);
2669:			return ERR_PTR(ret);
2670:		}
2671:	
2672:		/* create the default block */
2673:		ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
2674:		if (ret) {
2675:			kfree(ep_opts);
2676:			kfree(opts);
2677:			return ERR_PTR(ret);
2678:		}
2679:	
2680:		/* set up the default MIDI1 (that is mandatory) */
2681:		block_opts->info.midi1_num_groups = 1;
2682:	
2683:		config_group_init_type_name(&opts->func_inst.group, "",
2684:					    &f_midi2_func_type);
2685:	
2686:		config_group_init_type_name(&ep_opts->group, "ep.0",
2687:					    &f_midi2_ep_type);
2688:		configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
2689:	
2690:		config_group_init_type_name(&block_opts->group, "block.0",
2691:					    &f_midi2_block_type);
2692:		configfs_add_default_group(&block_opts->group, &ep_opts->group);
2693:	
2694:		return &opts->func_inst;
2695:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

214/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 51909
							output: 47
							thoughts: 34
						

Thoughts:
Okay, here's my interpretation of those thoughts, presented as a first-person expert summary:

**The Allocation Dilemma**

Ah, right, so *those* are dynamically allocated. `ep_opts` and `block_opts`... yes, they're definitely being allocated on the heap, not the stack. That's good to keep in mind, because that has significant implications for memory management. I have to be careful about when and how they're deallocated.

And then there's `f_midi2_free_inst`. It's crucial to remember that its sole responsibility is to free `opts`. I need to ensure that the lifetime of those option structures is managed correctly, and that the function handling deallocation understands the relationships between the data structures. Otherwise, I risk leaks or, even worse, using freed memory. I must double-check how these are linked to other data.



215/2 2026/07/30 14:17 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_free_inst]

Results:
map[SourceCode:2636:	static void f_midi2_free_inst(struct usb_function_instance *f)
2637:	{
2638:		struct f_midi2_opts *opts;
2639:	
2640:		opts = container_of(f, struct f_midi2_opts, func_inst);
2641:	
2642:		kfree(opts->info.iface_name);
2643:		kfree(opts);
2644:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

216/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 52351
							output: 44
							thoughts: 221
						

Thoughts:
**Analyzing a ConfigFS Memory Leak in the USB MIDI Gadget Driver**

Okay, so it looks like `ep_opts` and `block_opts` are leaking – not good. The immediate fix is clear: call `configfs_remove_default_groups` within `f_midi2_free_inst` and `f_midi2_ep_opts_release`. Seems straightforward enough, but the prompt wants more.

Right, the goal is to leverage past fixes for similar issues within this subsystem or specific files. It's about learning the patterns. So, I need to dig into the commit history of `drivers/usb/gadget/function/f_midi2.c` and potentially the broader `drivers/usb/gadget/` directory. I'm focusing on commits that address memory leaks, specifically those related to ConfigFS refcounting errors, or bugs manifesting in incorrect error paths. The aim is to identify established idioms, locking rules, or common patterns the developers have used when crafting fixes for these types of bugs. Hopefully, there will be lessons learned!



217/2 2026/07/30 14:17 tool git-log
0m Args:
map[Count:20 MessageRegexps:[memory leak] PathPrefix:drivers/usb/gadget/ Since:3 years]

Results:
map[Output:c8547c74988e usb: gadget: net2280: Fix double free in probe error path
e4f5ce990818 usb: gadget: f_eem: Fix memory leak in eem_unwrap
62783c30d78a USB: gadget: f_hid: Fix memory leak in hidg_bind error path
da1668997052 usb: gadget: f_midi: fix MIDI Streaming descriptor lengths
94d9bf671ae3 usb: gadget: f_tcm: Don't prepare BOT write request twice
]

218/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 52997
							output: 27
							thoughts: 32
						

Thoughts:
Okay, here's my interpretation of those thoughts, summarized in the first person, assuming the context is something I'm intimately familiar with as an expert:

**Internal Code Review: Checking Key Hashes**

Right, let's just quickly zero in on `62783c30d78a` and `e4f5ce990818`. Those seem to be two critical hashes, likely related to either a critical configuration setting, code commit, or data record within the system. My gut tells me these could be key identifiers within the security log. Time to refresh my memory on what they likely represent, and quickly correlate it against known anomalies. Let's see if those correlate with events I have seen. I'm going to start with the audit logs. From there, I'll go to the build system, and then the repository. I'm hoping I can refresh my memory on these items very quickly.



219/2 2026/07/30 14:17 tool git-show
0m Args:
map[Commit:62783c30d78a]

Results:
map[Output:commit 62783c30d78aecf9810dae46fd4d11420ad38b74
Author: Yuhao Jiang <danisjiang@gmail.com>
Date:   Mon Jun 23 17:48:44 2025 +0800

    USB: gadget: f_hid: Fix memory leak in hidg_bind error path
    
    In hidg_bind(), if alloc_workqueue() fails after usb_assign_descriptors()
    has successfully allocated the USB descriptors, the current error handling
    does not call usb_free_all_descriptors() to free the allocated descriptors,
    resulting in a memory leak.
    
    Restructure the error handling by adding proper cleanup labels:
    - fail_free_all: cleans up workqueue and descriptors
    - fail_free_descs: cleans up descriptors only
    - fail: original cleanup for earlier failures
    
    This ensures that allocated resources are properly freed in reverse order
    of their allocation, preventing the memory leak when alloc_workqueue() fails.
    
    Fixes: a139c98f760ef ("USB: gadget: f_hid: Add GET_REPORT via userspace IOCTL")
    Cc: stable@vger.kernel.org
    Signed-off-by: Yuhao Jiang <danisjiang@gmail.com>
    Link: https://lore.kernel.org/r/20250623094844.244977-1-danisjiang@gmail.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
index 97a62b926415..8e1d1e884050 100644
--- a/drivers/usb/gadget/function/f_hid.c
+++ b/drivers/usb/gadget/function/f_hid.c
@@ -1278,18 +1278,19 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
 
 	if (!hidg->workqueue) {
 		status = -ENOMEM;
-		goto fail;
+		goto fail_free_descs;
 	}
 
 	/* create char device */
 	cdev_init(&hidg->cdev, &f_hidg_fops);
 	status = cdev_device_add(&hidg->cdev, &hidg->dev);
 	if (status)
-		goto fail_free_descs;
+		goto fail_free_all;
 
 	return 0;
-fail_free_descs:
+fail_free_all:
 	destroy_workqueue(hidg->workqueue);
+fail_free_descs:
 	usb_free_all_descriptors(f);
 fail:
 	ERROR(f->config->cdev, "hidg_bind FAILED\n");
]

220/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 54023
							output: 26
							thoughts: 17
						

Thoughts:
Okay, here's my interpretation of that.

**Analyzing Commit e4f5ce990818**

Right, let's dive in. First, I need to check out commit `e4f5ce990818`. That hash tells me this is a specific snapshot in the codebase's history. I'm going to pull it up and immediately start thinking about context. What was happening around this commit in terms of development? What features were being worked on, what bug reports were open, and what part of the system does this touch? I'll probably start by looking at the commit message itself. Beyond the message, I'll need to immediately look at the diff. What files were changed, and how were they changed? Are we talking about a small, isolated fix, or a larger refactor that could have ripple effects? And I know a commit hash is a unique ID of a changeset.



221/2 2026/07/30 14:17 tool git-show
0m Args:
map[Commit:e4f5ce990818]

Results:
map[Output:commit e4f5ce990818d37930cd9fb0be29eee0553c59d9
Author: Kuen-Han Tsai <khtsai@google.com>
Date:   Mon Nov 3 20:17:59 2025 +0800

    usb: gadget: f_eem: Fix memory leak in eem_unwrap
    
    The existing code did not handle the failure case of usb_ep_queue in the
    command path, potentially leading to memory leaks.
    
    Improve error handling to free all allocated resources on usb_ep_queue
    failure. This patch continues to use goto logic for error handling, as the
    existing error handling is complex and not easily adaptable to auto-cleanup
    helpers.
    
    kmemleak results:
      unreferenced object 0xffffff895a512300 (size 240):
        backtrace:
          slab_post_alloc_hook+0xbc/0x3a4
          kmem_cache_alloc+0x1b4/0x358
          skb_clone+0x90/0xd8
          eem_unwrap+0x1cc/0x36c
      unreferenced object 0xffffff8a157f4000 (size 256):
        backtrace:
          slab_post_alloc_hook+0xbc/0x3a4
          __kmem_cache_alloc_node+0x1b4/0x2dc
          kmalloc_trace+0x48/0x140
          dwc3_gadget_ep_alloc_request+0x58/0x11c
          usb_ep_alloc_request+0x40/0xe4
          eem_unwrap+0x204/0x36c
      unreferenced object 0xffffff8aadbaac00 (size 128):
        backtrace:
          slab_post_alloc_hook+0xbc/0x3a4
          __kmem_cache_alloc_node+0x1b4/0x2dc
          __kmalloc+0x64/0x1a8
          eem_unwrap+0x218/0x36c
      unreferenced object 0xffffff89ccef3500 (size 64):
        backtrace:
          slab_post_alloc_hook+0xbc/0x3a4
          __kmem_cache_alloc_node+0x1b4/0x2dc
          kmalloc_trace+0x48/0x140
          eem_unwrap+0x238/0x36c
    
    Fixes: 4249d6fbc10f ("usb: gadget: eem: fix echo command packet response issue")
    Cc: stable@kernel.org
    Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
    Link: https://patch.msgid.link/20251103121814.1559719-1-khtsai@google.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c
index 6de81ea17274..edbbadad6138 100644
--- a/drivers/usb/gadget/function/f_eem.c
+++ b/drivers/usb/gadget/function/f_eem.c
@@ -477,8 +477,13 @@ static int eem_unwrap(struct gether *port,
 				req->complete = eem_cmd_complete;
 				req->zero = 1;
 				req->context = ctx;
-				if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC))
+				if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) {
 					DBG(cdev, "echo response queue fail\n");
+					kfree(ctx);
+					kfree(req->buf);
+					usb_ep_free_request(ep, req);
+					dev_kfree_skb_any(skb2);
+				}
 				break;
 
 			case 1:  /* echo response */
]

222/2 2026/07/30 14:17 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 55357
							output: 38
							thoughts: 36
						

Thoughts:
Okay, here's my interpretation of those thoughts, tailored for an expert audience, and delivered as a first-person summary:

**Memory Leak Deep Dive: Familiar Terrain**

Right, these seem to be classic, run-of-the-mill memory leaks, nothing particularly exotic to begin with. The initial instinct is to dig deeper into the code. The immediate next step is to perform a thorough search. A good starting point would be to search for instances of `configfs_remove_default_groups` across the entire kernel's history. This targeted search strategy will likely yield prior attempts to address similar memory management issues. The idea is to quickly leverage existing solutions, identify recurring patterns, and hopefully, find a precedent that will help quickly solve the issue at hand. Understanding what fixes have been employed in the past will give valuable context and save me time.



223/2 2026/07/30 14:17 tool git-log
10m Error:
git log timed out. Please specify a tighter search scope (e.g. by providing a PathPrefix).

Args:
map[CodeRegexp:configfs_remove_default_groups Count:20 Since:10 years]

Results:
map[Output:]

224/2 2026/07/30 14:27 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 55643
							output: 48
							thoughts: 22
						

Thoughts:
Okay, here's my thought process summarized from that prompt, tailored for an expert audience:

**Investigating `configfs_remove_default_groups` in the Target Subsystem**

Alright, let's dive into this. The objective is to understand how `configfs_remove_default_groups` is used, and in what context within the target subsystem (`drivers/target/`). My immediate instinct is to pinpoint its exact location and purpose. I'm assuming, given the name, it likely handles the removal of some default group configuration related to a ConfigFS object. This could be critical for security or resource management, depending on the specific implementation within the target framework. It is likely that this function is part of the clean up process.

Knowing how the ConfigFS is used in the Target subsystem is crucial. I'm thinking about the different target drivers (LIO, etc.) and how they might utilize ConfigFS for exporting various target related attributes. Does this function interact with user-created targets, or only remove a default that the kernel provides? Understanding the dependencies is going to be key, and I’ll need to trace the call graph to see what objects or other kernel calls it is dependent on.



225/2 2026/07/30 14:27 tool git-log
0m Args:
map[CodeRegexp:configfs_remove_default_groups Count:20 PathPrefix:drivers/target/ Since:10 years]

Results:
map[Output:39ae3edda325 scsi: target: core: Make completion affinity configurable
]

226/2 2026/07/30 14:27 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 55998
							output: 24
							thoughts: 15
						

Thoughts:
Okay, here's my attempt at summarizing the thought process, as requested, aimed at an expert user:

**Assessing the Significance of `39ae3edda325`**

Alright, let's take a look at this `39ae3edda325`. Immediately, the format screams something potentially crucial. Is it a hash? A version identifier? A commit hash? Based on the structure, it looks like a fairly standard hexadecimal string, so my initial assumption is that we are looking at something cryptographic or version based. I need more context to know for certain. I'm going to need to figure out the environment this identifier comes from to determine its significance. Is this within a log file? Code repository? Database? It could represent a file, a block of data, or a change.

If it *is* a hash, the next thing I'd want to determine is the hashing algorithm used. SHA-256? MD5? Something custom? That's going to dictate the level of trust I can place in its integrity and whether it's practically reversible or not. If it's a version identifier, I'll need to locate the metadata to determine the software or file it belongs to.

Ultimately, I need to understand *where* this value is coming from and what its intended purpose is. Once I figure that out, I can make a judgement on how important it is.



227/2 2026/07/30 14:27 tool git-show
0m Args:
map[Commit:39ae3edda325]

Results:
map[Output:commit 39ae3edda325e9cf9e978c9788affe88231f3b34
Author: Mike Christie <michael.christie@oracle.com>
Date:   Sat Feb 27 11:00:06 2021 -0600

    scsi: target: core: Make completion affinity configurable
    
    It may not always be best to complete the IO on same CPU as it was
    submitted on. This commit allows userspace to configure it.
    
    This has been useful for vhost-scsi where we have a single thread for
    submissions and completions. If we force the completion on the submission
    CPU we may be adding conflicts with what the user has setup in the lower
    levels with settings like the block layer rq_affinity or the driver's IRQ
    or softirq (the network's rps_cpus value) settings.
    
    We may also want to set it up where the vhost thread runs on CPU N and does
    its submissions/completions there, and then have LIO do its completion
    booking on CPU M, but can't configure the lower levels due to issues like
    using dm-multipath with lots of paths (the path selector can throw commands
    all over the system because it's only taking into account latency/throughput
    at its level).
    
    The new setting is in:
    
        /sys/kernel/config/target/$fabric/$target/param/cmd_completion_affinity
    
    Writing:
    
        -1 -> Gives the current default behavior of completing on the
              submission CPU.
    
        -2 -> Completes the cmd on the CPU the lower layers sent it to us from.
    
       > 0 -> Completes on the CPU userspace has specified.
    
    Link: https://lore.kernel.org/r/20210227170006.5077-26-michael.christie@oracle.com
    Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
    Signed-off-by: Mike Christie <michael.christie@oracle.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index ee85602213f7..fc7edc04ee09 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -892,6 +892,7 @@ static void target_fabric_release_wwn(struct config_item *item)
 	struct target_fabric_configfs *tf = wwn->wwn_tf;
 
 	configfs_remove_default_groups(&wwn->fabric_stat_group);
+	configfs_remove_default_groups(&wwn->param_group);
 	tf->tf_ops->fabric_drop_wwn(wwn);
 }
 
@@ -918,6 +919,57 @@ TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL);
 
 /* End of tfc_wwn_fabric_stats_cit */
 
+static ssize_t
+target_fabric_wwn_cmd_completion_affinity_show(struct config_item *item,
+					       char *page)
+{
+	struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn,
+					  param_group);
+	return sprintf(page, "%d\n",
+		       wwn->cmd_compl_affinity == WORK_CPU_UNBOUND ?
+		       SE_COMPL_AFFINITY_CURR_CPU : wwn->cmd_compl_affinity);
+}
+
+static ssize_t
+target_fabric_wwn_cmd_completion_affinity_store(struct config_item *item,
+						const char *page, size_t count)
+{
+	struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn,
+					  param_group);
+	int compl_val;
+
+	if (kstrtoint(page, 0, &compl_val))
+		return -EINVAL;
+
+	switch (compl_val) {
+	case SE_COMPL_AFFINITY_CPUID:
+		wwn->cmd_compl_affinity = compl_val;
+		break;
+	case SE_COMPL_AFFINITY_CURR_CPU:
+		wwn->cmd_compl_affinity = WORK_CPU_UNBOUND;
+		break;
+	default:
+		if (compl_val < 0 || compl_val >= nr_cpu_ids ||
+		    !cpu_online(compl_val)) {
+			pr_err("Command completion value must be between %d and %d or an online CPU.\n",
+			       SE_COMPL_AFFINITY_CPUID,
+			       SE_COMPL_AFFINITY_CURR_CPU);
+			return -EINVAL;
+		}
+		wwn->cmd_compl_affinity = compl_val;
+	}
+
+	return count;
+}
+CONFIGFS_ATTR(target_fabric_wwn_, cmd_completion_affinity);
+
+static struct configfs_attribute *target_fabric_wwn_param_attrs[] = {
+	&target_fabric_wwn_attr_cmd_completion_affinity,
+	NULL,
+};
+
+TF_CIT_SETUP(wwn_param, NULL, NULL, target_fabric_wwn_param_attrs);
+
 /* Start of tfc_wwn_cit */
 
 static struct config_group *target_fabric_make_wwn(
@@ -937,6 +989,7 @@ static struct config_group *target_fabric_make_wwn(
 	if (!wwn || IS_ERR(wwn))
 		return ERR_PTR(-EINVAL);
 
+	wwn->cmd_compl_affinity = SE_COMPL_AFFINITY_CPUID;
 	wwn->wwn_tf = tf;
 
 	config_group_init_type_name(&wwn->wwn_group, name, &tf->tf_tpg_cit);
@@ -945,6 +998,10 @@ static struct config_group *target_fabric_make_wwn(
 			&tf->tf_wwn_fabric_stats_cit);
 	configfs_add_default_group(&wwn->fabric_stat_group, &wwn->wwn_group);
 
+	config_group_init_type_name(&wwn->param_group, "param",
+			&tf->tf_wwn_param_cit);
+	configfs_add_default_group(&wwn->param_group, &wwn->wwn_group);
+
 	if (tf->tf_ops->add_wwn_groups)
 		tf->tf_ops->add_wwn_groups(wwn);
 	return &wwn->wwn_group;
@@ -974,6 +1031,7 @@ int target_fabric_setup_cits(struct target_fabric_configfs *tf)
 	target_fabric_setup_discovery_cit(tf);
 	target_fabric_setup_wwn_cit(tf);
 	target_fabric_setup_wwn_fabric_stats_cit(tf);
+	target_fabric_setup_wwn_param_cit(tf);
 	target_fabric_setup_tpg_cit(tf);
 	target_fabric_setup_tpg_base_cit(tf);
 	target_fabric_setup_tpg_port_cit(tf);
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index 56f841fd7f04..a343bcfa2180 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -34,6 +34,7 @@ struct target_fabric_configfs {
 	struct config_item_type tf_discovery_cit;
 	struct config_item_type	tf_wwn_cit;
 	struct config_item_type tf_wwn_fabric_stats_cit;
+	struct config_item_type tf_wwn_param_cit;
 	struct config_item_type tf_tpg_cit;
 	struct config_item_type tf_tpg_base_cit;
 	struct config_item_type tf_tpg_lun_cit;
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 1245c288d3bf..a75591c929c0 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -857,7 +857,8 @@ static bool target_cmd_interrupted(struct se_cmd *cmd)
 /* May be called from interrupt context so must not sleep. */
 void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
 {
-	int success;
+	struct se_wwn *wwn = cmd->se_sess->se_tpg->se_tpg_wwn;
+	int success, cpu;
 	unsigned long flags;
 
 	if (target_cmd_interrupted(cmd))
@@ -884,7 +885,13 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
 
 	INIT_WORK(&cmd->work, success ? target_complete_ok_work :
 		  target_complete_failure_work);
-	queue_work_on(cmd->cpuid, target_completion_wq, &cmd->work);
+
+	if (wwn->cmd_compl_affinity == SE_COMPL_AFFINITY_CPUID)
+		cpu = cmd->cpuid;
+	else
+		cpu = wwn->cmd_compl_affinity;
+
+	queue_work_on(cpu, target_completion_wq, &cmd->work);
 }
 EXPORT_SYMBOL(target_complete_cmd);
 
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index cf445c3a551a..d1f7d2a45354 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -944,11 +944,20 @@ static inline struct se_portal_group *param_to_tpg(struct config_item *item)
 			tpg_param_group);
 }
 
+enum {
+	/* Use se_cmd's cpuid for completion */
+	SE_COMPL_AFFINITY_CPUID		= -1,
+	/* Complete on current CPU */
+	SE_COMPL_AFFINITY_CURR_CPU	= -2,
+};
+
 struct se_wwn {
 	struct target_fabric_configfs *wwn_tf;
 	void			*priv;
 	struct config_group	wwn_group;
 	struct config_group	fabric_stat_group;
+	struct config_group	param_group;
+	int			cmd_compl_affinity;
 };
 
 static inline void atomic_inc_mb(atomic_t *v)
]

228/2 2026/07/30 14:27 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 59252
							output: 33
							thoughts: 71
						

Thoughts:
**Analyzing the Commit's Impact**

Okay, so this commit *introduces* a call to `configfs_remove_default_groups(&wwn->param_group)`. It's pretty straightforward: they added a new default group, `param_group`, and now they're cleaning it up properly. It's an *addition*, not a fix for a pre-existing oversight, which is a key distinction to keep in mind for future references.

I'm curious if this new functionality has been part of any broader discussions. I'll take a quick look through the commit messages to see if there's any mention of `configfs_remove_default_groups`. That might provide some context on the motivation and design decisions behind this change.



229/2 2026/07/30 14:28 tool git-log
0m Args:
map[MessageRegexps:[configfs_remove_default_groups] Since:10 years]

Results:
map[Output:3d2825c8c610 fs: dlm: fix configfs memory leak
]

230/2 2026/07/30 14:28 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 59552
							output: 27
							thoughts: 18
						

Thoughts:
Okay, let's dive into this. Here's my take on those thoughts, as if they're my own:

**Analyzing the Commit Hash**

Right, let's take a look at this commit hash, `3d2825c8c610`. Immediately, my mind starts sifting through the possibilities. Based on the format, it's a Git commit hash. The exact context, of course, is key. Is this in my current project? Or something I’m reviewing? That influences how deeply I'll dig initially.

My first thought is, where does this come from? Is it an issue someone reported? A colleague's code? My own recent work? That helps dictate the investigative strategy. I'll need to know the origin to really understand its significance.

Assuming I'm familiar with the codebase, my next step is likely to fire up the relevant tools: the Git client. I'll probably start with a `git show` to quickly glance at the commit message, the author, and the diff. That quick overview should give me the core context. If it's a simple, localized change, that might be enough to understand it. However, if the diff is complex or impacts a crucial area, I'll need to dig deeper.

I'll also keep in mind the potential impact. Are there associated tests? Any related pull requests? Does this relate to any known vulnerabilities or performance issues? I can't just look at the code in isolation.

If the hash isn't immediately familiar, I might perform a `git log --grep` search around it to understand where it appears in history, and maybe look at nearby commits that might give more context. This also helps with the context.

Ultimately, my goal is to grasp the intent of the change, how it was implemented, and the potential consequences. Armed with that knowledge, I can evaluate its correctness, its impact on the system, and its potential for improvement. It's a fundamental part of the review process, or just everyday software maintenance. Okay, time to check it out.



231/2 2026/07/30 14:28 tool git-show
0m Args:
map[Commit:3d2825c8c610]

Results:
map[Output:commit 3d2825c8c6105b0f36f3ff72760799fa2e71420e
Author: Alexander Aring <aahringo@redhat.com>
Date:   Thu Aug 27 15:02:51 2020 -0400

    fs: dlm: fix configfs memory leak
    
    This patch fixes the following memory detected by kmemleak and umount
    gfs2 filesystem which removed the last lockspace:
    
    unreferenced object 0xffff9264f482f600 (size 192):
      comm "dlm_controld", pid 325, jiffies 4294690276 (age 48.136s)
      hex dump (first 32 bytes):
        00 00 00 00 00 00 00 00 6e 6f 64 65 73 00 00 00  ........nodes...
        00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      backtrace:
        [<00000000060481d7>] make_space+0x41/0x130
        [<000000008d905d46>] configfs_mkdir+0x1a2/0x5f0
        [<00000000729502cf>] vfs_mkdir+0x155/0x210
        [<000000000369bcf1>] do_mkdirat+0x6d/0x110
        [<00000000cc478a33>] do_syscall_64+0x33/0x40
        [<00000000ce9ccf01>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    The patch just remembers the "nodes" entry pointer in space as I think
    it's created as subdirectory when parent "spaces" is created. In
    function drop_space() we will lost the pointer reference to nds because
    configfs_remove_default_groups(). However as this subdirectory is always
    available when "spaces" exists it will just be freed when "spaces" will be
    freed.
    
    Signed-off-by: Alexander Aring <aahringo@redhat.com>
    Signed-off-by: David Teigland <teigland@redhat.com>

diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index 47f0b98b707f..f33a7e4ae917 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -221,6 +221,7 @@ struct dlm_space {
 	struct list_head members;
 	struct mutex members_lock;
 	int members_count;
+	struct dlm_nodes *nds;
 };
 
 struct dlm_comms {
@@ -430,6 +431,7 @@ static struct config_group *make_space(struct config_group *g, const char *name)
 	INIT_LIST_HEAD(&sp->members);
 	mutex_init(&sp->members_lock);
 	sp->members_count = 0;
+	sp->nds = nds;
 	return &sp->group;
 
  fail:
@@ -451,6 +453,7 @@ static void drop_space(struct config_group *g, struct config_item *i)
 static void release_space(struct config_item *i)
 {
 	struct dlm_space *sp = config_item_to_space(i);
+	kfree(sp->nds);
 	kfree(sp);
 }
 
]

232/2 2026/07/30 14:28 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 61074
							output: 35
							thoughts: 201
						

Thoughts:
**Analyzing a Memory Leak Fix**

Okay, so I'm looking at commit `3d2825c8c610`, and it's flagged as fixing a memory leak in `fs/dlm/config.c`. My initial reaction is, "Right, let's see what they did." The commit message mentions `drop_space()` and a potential issue with `configfs_remove_default_groups()`. It's saying we could lose the pointer reference to `nds` because of that function, but since the subdirectory is "always available," it will just be freed when "spaces" is. My immediate thought is, "Okay, but let's break this down." `configfs_remove_default_groups()` implies a refcount drop on a default group, which then *should* trigger a release function. If that release function doesn't handle freeing the memory properly, we've got a leak.

Now I'm connecting the dots: in `fs/dlm/config.c`, `nds` is allocated within `make_space()` and is added as a default group. My immediate question is, "Did `nds` *have* a proper release function that would free its memory?" I don't see one in the original commit message. This sounds like an oversight. I'd better dive into that commit itself and confirm the fix. I'll check `fs/dlm/config.c` now and verify if the fix addresses the missing release function for `nds`.



233/2 2026/07/30 14:28 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/dlm/config.c Name:make_space]

Results:
map[SourceCode: 478:	static struct config_group *make_space(struct config_group *g, const char *name)
 479:	{
 480:		struct dlm_space *sp = NULL;
 481:		struct dlm_nodes *nds = NULL;
 482:	
 483:		sp = kzalloc_obj(struct dlm_space, GFP_NOFS);
 484:		nds = kzalloc_obj(struct dlm_nodes, GFP_NOFS);
 485:	
 486:		if (!sp || !nds)
 487:			goto fail;
 488:	
 489:		config_group_init_type_name(&sp->group, name, &space_type);
 490:	
 491:		config_group_init_type_name(&nds->ns_group, "nodes", &nodes_type);
 492:		configfs_add_default_group(&nds->ns_group, &sp->group);
 493:	
 494:		INIT_LIST_HEAD(&sp->members);
 495:		INIT_LIST_HEAD(&sp->members_gone);
 496:		mutex_init(&sp->members_lock);
 497:		sp->members_count = 0;
 498:		sp->nds = nds;
 499:		return &sp->group;
 500:	
 501:	 fail:
 502:		kfree(sp);
 503:		kfree(nds);
 504:		return ERR_PTR(-ENOMEM);
 505:	}
 SourceFile:fs/dlm/config.c]

234/2 2026/07/30 14:28 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 62089
							output: 35
							thoughts: 46
						

Thoughts:
Okay, let me think this through.

**Analyzing Potential Memory Leaks in the ConfigFS Space Driver**

Alright, hang on a second. This `drop_space` function is calling `configfs_remove_default_groups(&sp->group);`. That looks normal enough, but something's nagging at me. It's the `nds` object. It seems that the release function doesn't actually free the `nds` structure. That's a red flag. I need to be absolutely certain of this. Let me double-check the definition and usage of the `nodes_type` variable. I want to see how `nds` is handled within that context. Perhaps I'm missing something, or maybe there's an internal reference that's not obvious. This could indicate a significant memory leak, and I need to identify where that object is expected to be freed. Time to dig in!



235/2 2026/07/30 14:28 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/dlm/config.c Name:nodes_type]

Results:
map[SourceCode: 395:	static const struct config_item_type nodes_type = {
 396:		.ct_group_ops = &nodes_ops,
 397:		.ct_owner = THIS_MODULE,
 398:	};
 SourceFile:fs/dlm/config.c]

236/2 2026/07/30 14:28 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 62454
							output: 47
							thoughts: 126
						

Thoughts:
**Analyzing the `nodes_type` Refcount Issue**

Okay, hold on a second... It just hit me: `nodes_type` doesn't *have* a release function! That's a problem. So, when `configfs_remove_default_groups` decrements the reference count to zero, `nds` isn't actually getting freed. That explains the issue. Right, so I see how they addressed it – they moved the freeing of `nds` to `release_space`, which is the release function of the *parent* object. That's a reasonable workaround, but I need to make sure I understand the implications for my current work.

Now, let's apply this to the current context. In my scenario, with `f_midi2.c`, I'm dealing with `f_midi2_ep_type` and `f_midi2_block_type`. The critical question is whether *these* types have appropriate release functions. I need to verify that those do the equivalent of what `release_space` did in their case, ensuring proper cleanup. Let's start by digging into `f_midi2_ep_type`.



237/2 2026/07/30 14:28 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_ep_type]

Results:
map[SourceCode:2490:	static const struct config_item_type f_midi2_ep_type = {
2491:		.ct_item_ops	= &f_midi2_ep_item_ops,
2492:		.ct_group_ops	= &f_midi2_ep_group_ops,
2493:		.ct_attrs	= f_midi2_ep_attrs,
2494:		.ct_owner	= THIS_MODULE,
2495:	};
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

238/2 2026/07/30 14:28 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 63040
							output: 49
							thoughts: 16
						

Thoughts:
Okay, here's my interpretation of that thought process, assuming I'm an expert in this field and approaching a problem:

**Checking `f_midi2_ep_item_ops`**

Alright, time to dive in. My immediate thought is, "Okay, let's see what's going on with `f_midi2_ep_item_ops`." This function or module, whatever it is, is key to the current issue, or it's simply a place I know well and makes sense to check at this point. I need to get a clear picture of its behavior. Is it causing the bottleneck? Is it behaving as expected in the context of the rest of the system? I'll probably start by looking at its inputs and outputs, then trace its execution. Specifically, I'll be looking for any signs of performance bottlenecks or unexpected behavior related to how it handles MIDI data or interacts with the end-point item operations. Let's see if this answers the issue at hand.



239/2 2026/07/30 14:28 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_ep_item_ops]

Results:
map[SourceCode:2481:	static const struct configfs_item_operations f_midi2_ep_item_ops = {
2482:		.release	= f_midi2_ep_opts_release,
2483:	};
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

240/2 2026/07/30 14:28 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 63413
							output: 49
							thoughts: 16
						

Thoughts:
Here's a summary of my thought process, as if I were the one thinking it:

**Checking `f_midi2_ep_opts_release`**

Okay, time to take a look at `f_midi2_ep_opts_release`. I need to ensure this function is behaving as expected, especially in the current context. Let me quickly refresh my memory on what it's responsible for. Is it handling the release of endpoint options related to MIDI 2.0? Right, it's about cleaning up resources or signaling the end of a session, likely after a MIDI 2.0 exchange or configuration. I'll need to verify its interactions with the endpoint manager and resource allocation logic. Specifically, I'll be looking for potential memory leaks, dangling pointers, or incorrect state transitions after this function is called. Are all allocated resources properly freed? Is there correct error handling in case of failures during the release process? I need to check for any race conditions if multiple threads might be calling this function. Beyond the basics, I'll also glance at the surrounding code to ensure its called in all the necessary locations and not called in any unexpected ones. This is critical for maintaining stability and preventing unexpected behaviour in the system. Alright, let's start digging into the implementation and run a few tests.



241/2 2026/07/30 14:28 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_ep_opts_release]

Results:
map[SourceCode:2472:	static void f_midi2_ep_opts_release(struct config_item *item)
2473:	{
2474:		struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
2475:	
2476:		kfree(opts->info.ep_name);
2477:		kfree(opts->info.product_id);
2478:		kfree(opts);
2479:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

242/2 2026/07/30 14:28 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 63919
							output: 38
							thoughts: 200
						

Thoughts:
**My Analysis of the Memory Leak in the MIDI Driver**

Okay, it clicks! I see now – `f_midi2_ep_opts_release` *does* properly free the `opts` structure. So if `configfs_remove_default_groups` is invoked, we're golden; the memory is released. The crux of the issue, however, is that `configfs_remove_default_groups` *isn't* being called when it should be. The memory leaks because of this.

Right, the prompt is guiding me towards a more systematic approach. It wants me to hunt for precedent. I need to dig into past commits within this subsystem or related files, looking for fixes to similar memory management issues. The goal is to identify common patterns, locking rules, or idioms that were employed to resolve analogous bugs. The prompt is specifically looking for similar missing locks, incorrect reference counting, or similar error path bugs in the code. I must now focus on finding commit messages related to `configfs_remove_default_groups`, or similar removal functions, specifically where they were introduced to address memory leaks or resource management problems. If I find nothing, I need to be clear and state that. This is the path to a solid and effective fix.



243/2 2026/07/30 14:28 tool git-log
10m Error:
git log timed out. Please specify a tighter search scope (e.g. by providing a PathPrefix).

Args:
map[CodeRegexp:configfs_remove_default_groups Count:20 Since:15 years]

Results:
map[Output:]

244/2 2026/07/30 14:38 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 64455
							output: 51
							thoughts: 25
						

Thoughts:
Here's my thought process, as requested:

**Navigating the USB Gadget Landscape for Configuration Removal**

Okay, so I need to find where the system handles the removal of default groups within the USB gadget configuration system. My instinct tells me this is likely handled within the `drivers/usb/gadget/` directory, considering this is the kernel's central location for USB gadget-related code. Specifically, the function I'm after, `configfs_remove_default_groups`, seems like a pretty clear indicator of what I should search for. Let me go ahead and start digging in that directory. I'll need to use my usual tools to pinpoint the exact location. Hopefully, the naming is straightforward enough that it leads me directly to the relevant files.



245/2 2026/07/30 14:39 tool git-log
0m Args:
map[CodeRegexp:configfs_remove_default_groups Count:20 PathPrefix:drivers/usb/gadget/ Since:15 years]

Results:
map[Output:]

246/2 2026/07/30 14:39 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 64704
							output: 51
							thoughts: 90
						

Thoughts:
Okay, here's my thought process on this, distilled into a first-person summary:

**USB Gadget Driver Configuration Oversight**

Alright, I'm digging into this `configfs_remove_default_groups` situation. First off, I'm a bit puzzled. No recent commits in the `drivers/usb/gadget/` directory are actually *using* `configfs_remove_default_groups`. That's a red flag. If they aren't using this method, how are they dealing with equivalent problems? Are they just letting the underlying filesystem's default configurations stand, and, if so, is this creating potential vulnerabilities?

Okay, let's step back and re-examine `uvcg_config_remove_children`. I know I've seen it before, but perhaps I missed something. I need to understand if this is related.

Okay, I need to understand when `uvcg_config_remove_children` was added; understanding that timeline is critical to understanding the bigger picture.



247/2 2026/07/30 14:39 tool git-log
0m Args:
map[CodeRegexp:uvcg_config_remove_children Count:20 PathPrefix:drivers/usb/gadget/ Since:15 years]

Results:
map[Output:efbf0af70b4f usb: gadget: uvc: configfs: Allocate groups dynamically
]

248/2 2026/07/30 14:39 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 65097
							output: 24
							thoughts: 15
						

Thoughts:
Okay, let's dive into this. Here's my thought process on this task:

**Analyzing the Hash `efbf0af70b4f`**

Alright, the instruction says to "check `efbf0af70b4f`." My initial thought is, this looks like a cryptographic hash, likely a result of some hashing algorithm. Without any context, the first thing I'd do is *assume* it's a hexadecimal representation. I need to figure out the likely algorithm used. Given its length (12 characters), it's probably not MD5 (32 chars) or SHA-256 (64 chars). It could be something shorter, like a truncated SHA variant, or maybe something custom. I would probably first try to identify it with a online hash identifier. I would also try to understand its likely purpose: is it a file hash, password hash, or something else entirely? Then, I would try a quick check in my internal databases for known hashes, in case I’ve seen this before.  I'd also consider if this hash might be a partial fragment of a larger hash and need to be looked at in context. It's a starting point and I need to do some more digging before drawing any conclusions.



249/2 2026/07/30 14:39 tool git-show
0m Args:
map[Commit:efbf0af70b4f]

Results:
map[Output:commit efbf0af70b4f7ee6ed1533ed0d905255c0545e08
Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Date:   Thu May 24 17:49:34 2018 +0300

    usb: gadget: uvc: configfs: Allocate groups dynamically
    
    The UVC configfs implementation creates all groups as global static
    variables. This prevents creation of multiple UVC function instances,
    as they would all require their own configfs group instances.
    
    Fix this by allocating all groups dynamically. To avoid duplicating code
    around, extend the config_item_type structure with group name and
    children, and implement helper functions to create children
    automatically for most groups.
    
    Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
    Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
index d8ce7868fe22..95cb1b5f5ffe 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -792,6 +792,7 @@ static struct usb_function_instance *uvc_alloc_inst(void)
 	struct uvc_output_terminal_descriptor *od;
 	struct uvc_color_matching_descriptor *md;
 	struct uvc_descriptor_header **ctl_cls;
+	int ret;
 
 	opts = kzalloc(sizeof(*opts), GFP_KERNEL);
 	if (!opts)
@@ -868,7 +869,12 @@ static struct usb_function_instance *uvc_alloc_inst(void)
 	opts->streaming_interval = 1;
 	opts->streaming_maxpacket = 1024;
 
-	uvcg_attach_configfs(opts);
+	ret = uvcg_attach_configfs(opts);
+	if (ret < 0) {
+		kfree(opts);
+		return ERR_PTR(ret);
+	}
+
 	return &opts->func_inst;
 }
 
diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
index 8d513cc6fb8c..ae722549eabc 100644
--- a/drivers/usb/gadget/function/uvc_configfs.c
+++ b/drivers/usb/gadget/function/uvc_configfs.c
@@ -41,6 +41,71 @@ static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item)
 			    func_inst.group);
 }
 
+struct uvcg_config_group_type {
+	struct config_item_type type;
+	const char *name;
+	const struct uvcg_config_group_type **children;
+	int (*create_children)(struct config_group *group);
+};
+
+static void uvcg_config_item_release(struct config_item *item)
+{
+	struct config_group *group = to_config_group(item);
+
+	kfree(group);
+}
+
+static struct configfs_item_operations uvcg_config_item_ops = {
+	.release	= uvcg_config_item_release,
+};
+
+static int uvcg_config_create_group(struct config_group *parent,
+				    const struct uvcg_config_group_type *type);
+
+static int uvcg_config_create_children(struct config_group *group,
+				const struct uvcg_config_group_type *type)
+{
+	const struct uvcg_config_group_type **child;
+	int ret;
+
+	if (type->create_children)
+		return type->create_children(group);
+
+	for (child = type->children; child && *child; ++child) {
+		ret = uvcg_config_create_group(group, *child);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int uvcg_config_create_group(struct config_group *parent,
+				    const struct uvcg_config_group_type *type)
+{
+	struct config_group *group;
+
+	group = kzalloc(sizeof(*group), GFP_KERNEL);
+	if (!group)
+		return -ENOMEM;
+
+	config_group_init_type_name(group, type->name, &type->type);
+	configfs_add_default_group(group, parent);
+
+	return uvcg_config_create_children(group, type);
+}
+
+static void uvcg_config_remove_children(struct config_group *group)
+{
+	struct config_group *child, *n;
+
+	list_for_each_entry_safe(child, n, &group->default_groups, group_entry) {
+		list_del(&child->group_entry);
+		uvcg_config_remove_children(child);
+		config_item_put(&child->cg_item);
+	}
+}
+
 /* -----------------------------------------------------------------------------
  * control/header/<NAME>
  * control/header
@@ -137,6 +202,7 @@ static struct configfs_attribute *uvcg_control_header_attrs[] = {
 };
 
 static const struct config_item_type uvcg_control_header_type = {
+	.ct_item_ops	= &uvcg_config_item_ops,
 	.ct_attrs	= uvcg_control_header_attrs,
 	.ct_owner	= THIS_MODULE,
 };
@@ -161,32 +227,23 @@ static struct config_item *uvcg_control_header_make(struct config_group *group,
 	return &h->item;
 }
 
-static void uvcg_control_header_drop(struct config_group *group,
-			      struct config_item *item)
-{
-	struct uvcg_control_header *h = to_uvcg_control_header(item);
-
-	kfree(h);
-}
-
-static struct config_group uvcg_control_header_grp;
-
 static struct configfs_group_operations uvcg_control_header_grp_ops = {
 	.make_item		= uvcg_control_header_make,
-	.drop_item		= uvcg_control_header_drop,
 };
 
-static const struct config_item_type uvcg_control_header_grp_type = {
-	.ct_group_ops	= &uvcg_control_header_grp_ops,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_control_header_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_group_ops	= &uvcg_control_header_grp_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "header",
 };
 
 /* -----------------------------------------------------------------------------
  * control/processing/default
  */
 
-static struct config_group uvcg_default_processing_grp;
-
 #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, conv)		\
 static ssize_t uvcg_default_processing_##cname##_show(			\
 	struct config_item *item, char *page)				\
@@ -265,27 +322,35 @@ static struct configfs_attribute *uvcg_default_processing_attrs[] = {
 	NULL,
 };
 
-static const struct config_item_type uvcg_default_processing_type = {
-	.ct_attrs	= uvcg_default_processing_attrs,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_default_processing_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_attrs	= uvcg_default_processing_attrs,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "default",
 };
 
 /* -----------------------------------------------------------------------------
  * control/processing
  */
 
-static struct config_group uvcg_processing_grp;
-
-static const struct config_item_type uvcg_processing_grp_type = {
-	.ct_owner = THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_processing_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "processing",
+	.children = (const struct uvcg_config_group_type*[]) {
+		&uvcg_default_processing_type,
+		NULL,
+	},
 };
 
 /* -----------------------------------------------------------------------------
  * control/terminal/camera/default
  */
 
-static struct config_group uvcg_default_camera_grp;
-
 #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, conv)			\
 static ssize_t uvcg_default_camera_##cname##_show(			\
 	struct config_item *item, char *page)				\
@@ -375,27 +440,35 @@ static struct configfs_attribute *uvcg_default_camera_attrs[] = {
 	NULL,
 };
 
-static const struct config_item_type uvcg_default_camera_type = {
-	.ct_attrs	= uvcg_default_camera_attrs,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_default_camera_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_attrs	= uvcg_default_camera_attrs,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "default",
 };
 
 /* -----------------------------------------------------------------------------
  * control/terminal/camera
  */
 
-static struct config_group uvcg_camera_grp;
-
-static const struct config_item_type uvcg_camera_grp_type = {
-	.ct_owner = THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_camera_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "camera",
+	.children = (const struct uvcg_config_group_type*[]) {
+		&uvcg_default_camera_type,
+		NULL,
+	},
 };
 
 /* -----------------------------------------------------------------------------
  * control/terminal/output/default
  */
 
-static struct config_group uvcg_default_output_grp;
-
 #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, conv)			\
 static ssize_t uvcg_default_output_##cname##_show(			\
 	struct config_item *item, char *page)				\
@@ -446,47 +519,68 @@ static struct configfs_attribute *uvcg_default_output_attrs[] = {
 	NULL,
 };
 
-static const struct config_item_type uvcg_default_output_type = {
-	.ct_attrs	= uvcg_default_output_attrs,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_default_output_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_attrs	= uvcg_default_output_attrs,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "default",
 };
 
 /* -----------------------------------------------------------------------------
  * control/terminal/output
  */
 
-static struct config_group uvcg_output_grp;
-
-static const struct config_item_type uvcg_output_grp_type = {
-	.ct_owner = THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_output_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "output",
+	.children = (const struct uvcg_config_group_type*[]) {
+		&uvcg_default_output_type,
+		NULL,
+	},
 };
 
 /* -----------------------------------------------------------------------------
  * control/terminal
  */
 
-static struct config_group uvcg_terminal_grp;
-
-static const struct config_item_type uvcg_terminal_grp_type = {
-	.ct_owner = THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_terminal_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "terminal",
+	.children = (const struct uvcg_config_group_type*[]) {
+		&uvcg_camera_grp_type,
+		&uvcg_output_grp_type,
+		NULL,
+	},
 };
 
 /* -----------------------------------------------------------------------------
  * control/class/{fs|ss}
  */
 
-static struct config_group uvcg_control_class_fs_grp;
-static struct config_group uvcg_control_class_ss_grp;
+struct uvcg_control_class_group {
+	struct config_group group;
+	const char *name;
+};
 
 static inline struct uvc_descriptor_header
 **uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o)
 {
-	struct config_group *group = to_config_group(i);
+	struct uvcg_control_class_group *group =
+		container_of(i, struct uvcg_control_class_group,
+			     group.cg_item);
 
-	if (group == &uvcg_control_class_fs_grp)
+	if (!strcmp(group->name, "fs"))
 		return o->uvc_fs_control_cls;
 
-	if (group == &uvcg_control_class_ss_grp)
+	if (!strcmp(group->name, "ss"))
 		return o->uvc_ss_control_cls;
 
 	return NULL;
@@ -570,6 +664,7 @@ static void uvcg_control_class_drop_link(struct config_item *src,
 }
 
 static struct configfs_item_operations uvcg_control_class_item_ops = {
+	.release	= uvcg_config_item_release,
 	.allow_link	= uvcg_control_class_allow_link,
 	.drop_link	= uvcg_control_class_drop_link,
 };
@@ -583,20 +678,54 @@ static const struct config_item_type uvcg_control_class_type = {
  * control/class
  */
 
-static struct config_group uvcg_control_class_grp;
+static int uvcg_control_class_create_children(struct config_group *parent)
+{
+	static const char * const names[] = { "fs", "ss" };
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(names); ++i) {
+		struct uvcg_control_class_group *group;
 
-static const struct config_item_type uvcg_control_class_grp_type = {
-	.ct_owner = THIS_MODULE,
+		group = kzalloc(sizeof(*group), GFP_KERNEL);
+		if (!group)
+			return -ENOMEM;
+
+		group->name = names[i];
+
+		config_group_init_type_name(&group->group, group->name,
+					    &uvcg_control_class_type);
+		configfs_add_default_group(&group->group, parent);
+	}
+
+	return 0;
+}
+
+static const struct uvcg_config_group_type uvcg_control_class_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "class",
+	.create_children = uvcg_control_class_create_children,
 };
 
 /* -----------------------------------------------------------------------------
  * control
  */
 
-static struct config_group uvcg_control_grp;
-
-static const struct config_item_type uvcg_control_grp_type = {
-	.ct_owner = THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_control_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "control",
+	.children = (const struct uvcg_config_group_type*[]) {
+		&uvcg_control_header_grp_type,
+		&uvcg_processing_grp_type,
+		&uvcg_terminal_grp_type,
+		&uvcg_control_class_grp_type,
+		NULL,
+	},
 };
 
 /* -----------------------------------------------------------------------------
@@ -604,12 +733,9 @@ static const struct config_item_type uvcg_control_grp_type = {
  * streaming/mjpeg
  */
 
-static struct config_group uvcg_uncompressed_grp;
-static struct config_group uvcg_mjpeg_grp;
-
-static struct config_item *fmt_parent[] = {
-	&uvcg_uncompressed_grp.cg_item,
-	&uvcg_mjpeg_grp.cg_item,
+static const char * const uvcg_format_names[] = {
+	"uncompressed",
+	"mjpeg",
 };
 
 enum uvcg_format_type {
@@ -735,10 +861,22 @@ static int uvcg_streaming_header_allow_link(struct config_item *src,
 		goto out;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(fmt_parent); ++i)
-		if (target->ci_parent == fmt_parent[i])
+	/*
+	 * Linking is only allowed to direct children of the format nodes
+	 * (streaming/uncompressed or streaming/mjpeg nodes). First check that
+	 * the grand-parent of the target matches the grand-parent of the source
+	 * (the streaming node), and then verify that the target parent is a
+	 * format node.
+	 */
+	if (src->ci_parent->ci_parent != target->ci_parent->ci_parent)
+		goto out;
+
+	for (i = 0; i < ARRAY_SIZE(uvcg_format_names); ++i) {
+		if (!strcmp(target->ci_parent->ci_name, uvcg_format_names[i]))
 			break;
-	if (i == ARRAY_SIZE(fmt_parent))
+	}
+
+	if (i == ARRAY_SIZE(uvcg_format_names))
 		goto out;
 
 	target_fmt = container_of(to_config_group(target), struct uvcg_format,
@@ -798,8 +936,9 @@ static void uvcg_streaming_header_drop_link(struct config_item *src,
 }
 
 static struct configfs_item_operations uvcg_streaming_header_item_ops = {
-	.allow_link		= uvcg_streaming_header_allow_link,
-	.drop_link		= uvcg_streaming_header_drop_link,
+	.release	= uvcg_config_item_release,
+	.allow_link	= uvcg_streaming_header_allow_link,
+	.drop_link	= uvcg_streaming_header_drop_link,
 };
 
 #define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv)			\
@@ -875,24 +1014,17 @@ static struct config_item
 	return &h->item;
 }
 
-static void uvcg_streaming_header_drop(struct config_group *group,
-			      struct config_item *item)
-{
-	struct uvcg_streaming_header *h = to_uvcg_streaming_header(item);
-
-	kfree(h);
-}
-
-static struct config_group uvcg_streaming_header_grp;
-
 static struct configfs_group_operations uvcg_streaming_header_grp_ops = {
 	.make_item		= uvcg_streaming_header_make,
-	.drop_item		= uvcg_streaming_header_drop,
 };
 
-static const struct config_item_type uvcg_streaming_header_grp_type = {
-	.ct_group_ops	= &uvcg_streaming_header_grp_ops,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_group_ops	= &uvcg_streaming_header_grp_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "header",
 };
 
 /* -----------------------------------------------------------------------------
@@ -900,6 +1032,8 @@ static const struct config_item_type uvcg_streaming_header_grp_type = {
  */
 
 struct uvcg_frame {
+	struct config_item	item;
+	enum uvcg_format_type	fmt_type;
 	struct {
 		u8	b_length;
 		u8	b_descriptor_type;
@@ -915,8 +1049,6 @@ struct uvcg_frame {
 		u8	b_frame_interval_type;
 	} __attribute__((packed)) frame;
 	u32 *dw_frame_interval;
-	enum uvcg_format_type	fmt_type;
-	struct config_item	item;
 };
 
 static struct uvcg_frame *to_uvcg_frame(struct config_item *item)
@@ -1143,6 +1275,7 @@ static struct configfs_attribute *uvcg_frame_attrs[] = {
 };
 
 static const struct config_item_type uvcg_frame_type = {
+	.ct_item_ops	= &uvcg_config_item_ops,
 	.ct_attrs	= uvcg_frame_attrs,
 	.ct_owner	= THIS_MODULE,
 };
@@ -1194,7 +1327,6 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
 
 static void uvcg_frame_drop(struct config_group *group, struct config_item *item)
 {
-	struct uvcg_frame *h = to_uvcg_frame(item);
 	struct uvcg_format *fmt;
 	struct f_uvc_opts *opts;
 	struct config_item *opts_item;
@@ -1205,8 +1337,9 @@ static void uvcg_frame_drop(struct config_group *group, struct config_item *item
 	mutex_lock(&opts->lock);
 	fmt = to_uvcg_format(&group->cg_item);
 	--fmt->num_frames;
-	kfree(h);
 	mutex_unlock(&opts->lock);
+
+	config_item_put(item);
 }
 
 /* -----------------------------------------------------------------------------
@@ -1415,6 +1548,7 @@ static struct configfs_attribute *uvcg_uncompressed_attrs[] = {
 };
 
 static const struct config_item_type uvcg_uncompressed_type = {
+	.ct_item_ops	= &uvcg_config_item_ops,
 	.ct_group_ops	= &uvcg_uncompressed_group_ops,
 	.ct_attrs	= uvcg_uncompressed_attrs,
 	.ct_owner	= THIS_MODULE,
@@ -1451,22 +1585,17 @@ static struct config_group *uvcg_uncompressed_make(struct config_group *group,
 	return &h->fmt.group;
 }
 
-static void uvcg_uncompressed_drop(struct config_group *group,
-			    struct config_item *item)
-{
-	struct uvcg_uncompressed *h = to_uvcg_uncompressed(item);
-
-	kfree(h);
-}
-
 static struct configfs_group_operations uvcg_uncompressed_grp_ops = {
 	.make_group		= uvcg_uncompressed_make,
-	.drop_item		= uvcg_uncompressed_drop,
 };
 
-static const struct config_item_type uvcg_uncompressed_grp_type = {
-	.ct_group_ops	= &uvcg_uncompressed_grp_ops,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_group_ops	= &uvcg_uncompressed_grp_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "uncompressed",
 };
 
 /* -----------------------------------------------------------------------------
@@ -1618,6 +1747,7 @@ static struct configfs_attribute *uvcg_mjpeg_attrs[] = {
 };
 
 static const struct config_item_type uvcg_mjpeg_type = {
+	.ct_item_ops	= &uvcg_config_item_ops,
 	.ct_group_ops	= &uvcg_mjpeg_group_ops,
 	.ct_attrs	= uvcg_mjpeg_attrs,
 	.ct_owner	= THIS_MODULE,
@@ -1648,30 +1778,23 @@ static struct config_group *uvcg_mjpeg_make(struct config_group *group,
 	return &h->fmt.group;
 }
 
-static void uvcg_mjpeg_drop(struct config_group *group,
-			    struct config_item *item)
-{
-	struct uvcg_mjpeg *h = to_uvcg_mjpeg(item);
-
-	kfree(h);
-}
-
 static struct configfs_group_operations uvcg_mjpeg_grp_ops = {
 	.make_group		= uvcg_mjpeg_make,
-	.drop_item		= uvcg_mjpeg_drop,
 };
 
-static const struct config_item_type uvcg_mjpeg_grp_type = {
-	.ct_group_ops	= &uvcg_mjpeg_grp_ops,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_group_ops	= &uvcg_mjpeg_grp_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "mjpeg",
 };
 
 /* -----------------------------------------------------------------------------
  * streaming/color_matching/default
  */
 
-static struct config_group uvcg_default_color_matching_grp;
-
 #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv)		\
 static ssize_t uvcg_default_color_matching_##cname##_show(		\
 	struct config_item *item, char *page)			\
@@ -1719,41 +1842,54 @@ static struct configfs_attribute *uvcg_default_color_matching_attrs[] = {
 	NULL,
 };
 
-static const struct config_item_type uvcg_default_color_matching_type = {
-	.ct_attrs	= uvcg_default_color_matching_attrs,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_default_color_matching_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_attrs	= uvcg_default_color_matching_attrs,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "default",
 };
 
 /* -----------------------------------------------------------------------------
  * streaming/color_matching
  */
 
-static struct config_group uvcg_color_matching_grp;
-
-static const struct config_item_type uvcg_color_matching_grp_type = {
-	.ct_owner = THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_color_matching_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "color_matching",
+	.children = (const struct uvcg_config_group_type*[]) {
+		&uvcg_default_color_matching_type,
+		NULL,
+	},
 };
 
 /* -----------------------------------------------------------------------------
  * streaming/class/{fs|hs|ss}
  */
 
-static struct config_group uvcg_streaming_class_fs_grp;
-static struct config_group uvcg_streaming_class_hs_grp;
-static struct config_group uvcg_streaming_class_ss_grp;
+struct uvcg_streaming_class_group {
+	struct config_group group;
+	const char *name;
+};
 
 static inline struct uvc_descriptor_header
 ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o)
 {
-	struct config_group *group = to_config_group(i);
+	struct uvcg_streaming_class_group *group =
+		container_of(i, struct uvcg_streaming_class_group,
+			     group.cg_item);
 
-	if (group == &uvcg_streaming_class_fs_grp)
+	if (!strcmp(group->name, "fs"))
 		return &o->uvc_fs_streaming_cls;
 
-	if (group == &uvcg_streaming_class_hs_grp)
+	if (!strcmp(group->name, "hs"))
 		return &o->uvc_hs_streaming_cls;
 
-	if (group == &uvcg_streaming_class_ss_grp)
+	if (!strcmp(group->name, "ss"))
 		return &o->uvc_ss_streaming_cls;
 
 	return NULL;
@@ -2074,6 +2210,7 @@ static void uvcg_streaming_class_drop_link(struct config_item *src,
 }
 
 static struct configfs_item_operations uvcg_streaming_class_item_ops = {
+	.release	= uvcg_config_item_release,
 	.allow_link	= uvcg_streaming_class_allow_link,
 	.drop_link	= uvcg_streaming_class_drop_link,
 };
@@ -2087,35 +2224,71 @@ static const struct config_item_type uvcg_streaming_class_type = {
  * streaming/class
  */
 
-static struct config_group uvcg_streaming_class_grp;
+static int uvcg_streaming_class_create_children(struct config_group *parent)
+{
+	static const char * const names[] = { "fs", "hs", "ss" };
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(names); ++i) {
+		struct uvcg_streaming_class_group *group;
+
+		group = kzalloc(sizeof(*group), GFP_KERNEL);
+		if (!group)
+			return -ENOMEM;
+
+		group->name = names[i];
 
-static const struct config_item_type uvcg_streaming_class_grp_type = {
-	.ct_owner = THIS_MODULE,
+		config_group_init_type_name(&group->group, group->name,
+					    &uvcg_streaming_class_type);
+		configfs_add_default_group(&group->group, parent);
+	}
+
+	return 0;
+}
+
+static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "class",
+	.create_children = uvcg_streaming_class_create_children,
 };
 
 /* -----------------------------------------------------------------------------
  * streaming
  */
 
-static struct config_group uvcg_streaming_grp;
-
-static const struct config_item_type uvcg_streaming_grp_type = {
-	.ct_owner = THIS_MODULE,
+static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
+	.type = {
+		.ct_item_ops	= &uvcg_config_item_ops,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "streaming",
+	.children = (const struct uvcg_config_group_type*[]) {
+		&uvcg_streaming_header_grp_type,
+		&uvcg_uncompressed_grp_type,
+		&uvcg_mjpeg_grp_type,
+		&uvcg_color_matching_grp_type,
+		&uvcg_streaming_class_grp_type,
+		NULL,
+	},
 };
 
 /* -----------------------------------------------------------------------------
  * UVC function
  */
 
-static void uvc_attr_release(struct config_item *item)
+static void uvc_func_item_release(struct config_item *item)
 {
 	struct f_uvc_opts *opts = to_f_uvc_opts(item);
 
+	uvcg_config_remove_children(to_config_group(item));
 	usb_put_function_instance(&opts->func_inst);
 }
 
-static struct configfs_item_operations uvc_item_ops = {
-	.release		= uvc_attr_release,
+static struct configfs_item_operations uvc_func_item_ops = {
+	.release	= uvc_func_item_release,
 };
 
 #define UVCG_OPTS_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit)	\
@@ -2183,123 +2356,31 @@ static struct configfs_attribute *uvc_attrs[] = {
 	NULL,
 };
 
-static const struct config_item_type uvc_func_type = {
-	.ct_item_ops	= &uvc_item_ops,
-	.ct_attrs	= uvc_attrs,
-	.ct_owner	= THIS_MODULE,
+static const struct uvcg_config_group_type uvc_func_type = {
+	.type = {
+		.ct_item_ops	= &uvc_func_item_ops,
+		.ct_attrs	= uvc_attrs,
+		.ct_owner	= THIS_MODULE,
+	},
+	.name = "",
+	.children = (const struct uvcg_config_group_type*[]) {
+		&uvcg_control_grp_type,
+		&uvcg_streaming_grp_type,
+		NULL,
+	},
 };
 
 int uvcg_attach_configfs(struct f_uvc_opts *opts)
 {
-	config_group_init_type_name(&uvcg_control_header_grp,
-				    "header",
-				    &uvcg_control_header_grp_type);
-
-	config_group_init_type_name(&uvcg_default_processing_grp,
-			"default", &uvcg_default_processing_type);
-	config_group_init_type_name(&uvcg_processing_grp,
-			"processing", &uvcg_processing_grp_type);
-	configfs_add_default_group(&uvcg_default_processing_grp,
-			&uvcg_processing_grp);
-
-	config_group_init_type_name(&uvcg_default_camera_grp,
-			"default", &uvcg_default_camera_type);
-	config_group_init_type_name(&uvcg_camera_grp,
-			"camera", &uvcg_camera_grp_type);
-	configfs_add_default_group(&uvcg_default_camera_grp,
-			&uvcg_camera_grp);
-
-	config_group_init_type_name(&uvcg_default_output_grp,
-			"default", &uvcg_default_output_type);
-	config_group_init_type_name(&uvcg_output_grp,
-			"output", &uvcg_output_grp_type);
-	configfs_add_default_group(&uvcg_default_output_grp,
-			&uvcg_output_grp);
-
-	config_group_init_type_name(&uvcg_terminal_grp,
-			"terminal", &uvcg_terminal_grp_type);
-	configfs_add_default_group(&uvcg_camera_grp,
-			&uvcg_terminal_grp);
-	configfs_add_default_group(&uvcg_output_grp,
-			&uvcg_terminal_grp);
-
-	config_group_init_type_name(&uvcg_control_class_fs_grp,
-			"fs", &uvcg_control_class_type);
-	config_group_init_type_name(&uvcg_control_class_ss_grp,
-			"ss", &uvcg_control_class_type);
-	config_group_init_type_name(&uvcg_control_class_grp,
-			"class",
-			&uvcg_control_class_grp_type);
-	configfs_add_default_group(&uvcg_control_class_fs_grp,
-			&uvcg_control_class_grp);
-	configfs_add_default_group(&uvcg_control_class_ss_grp,
-			&uvcg_control_class_grp);
-
-	config_group_init_type_name(&uvcg_control_grp,
-			"control",
-			&uvcg_control_grp_type);
-	configfs_add_default_group(&uvcg_control_header_grp,
-			&uvcg_control_grp);
-	configfs_add_default_group(&uvcg_processing_grp,
-			&uvcg_control_grp);
-	configfs_add_default_group(&uvcg_terminal_grp,
-			&uvcg_control_grp);
-	configfs_add_default_group(&uvcg_control_class_grp,
-			&uvcg_control_grp);
-
-	config_group_init_type_name(&uvcg_streaming_header_grp,
-				    "header",
-				    &uvcg_streaming_header_grp_type);
-	config_group_init_type_name(&uvcg_uncompressed_grp,
-				    "uncompressed",
-				    &uvcg_uncompressed_grp_type);
-	config_group_init_type_name(&uvcg_mjpeg_grp,
-				    "mjpeg",
-				    &uvcg_mjpeg_grp_type);
-	config_group_init_type_name(&uvcg_default_color_matching_grp,
-				    "default",
-				    &uvcg_default_color_matching_type);
-	config_group_init_type_name(&uvcg_color_matching_grp,
-			"color_matching",
-			&uvcg_color_matching_grp_type);
-	configfs_add_default_group(&uvcg_default_color_matching_grp,
-			&uvcg_color_matching_grp);
-
-	config_group_init_type_name(&uvcg_streaming_class_fs_grp,
-			"fs", &uvcg_streaming_class_type);
-	config_group_init_type_name(&uvcg_streaming_class_hs_grp,
-			"hs", &uvcg_streaming_class_type);
-	config_group_init_type_name(&uvcg_streaming_class_ss_grp,
-			"ss", &uvcg_streaming_class_type);
-	config_group_init_type_name(&uvcg_streaming_class_grp,
-			"class", &uvcg_streaming_class_grp_type);
-	configfs_add_default_group(&uvcg_streaming_class_fs_grp,
-			&uvcg_streaming_class_grp);
-	configfs_add_default_group(&uvcg_streaming_class_hs_grp,
-			&uvcg_streaming_class_grp);
-	configfs_add_default_group(&uvcg_streaming_class_ss_grp,
-			&uvcg_streaming_class_grp);
-
-	config_group_init_type_name(&uvcg_streaming_grp,
-			"streaming", &uvcg_streaming_grp_type);
-	configfs_add_default_group(&uvcg_streaming_header_grp,
-			&uvcg_streaming_grp);
-	configfs_add_default_group(&uvcg_uncompressed_grp,
-			&uvcg_streaming_grp);
-	configfs_add_default_group(&uvcg_mjpeg_grp,
-			&uvcg_streaming_grp);
-	configfs_add_default_group(&uvcg_color_matching_grp,
-			&uvcg_streaming_grp);
-	configfs_add_default_group(&uvcg_streaming_class_grp,
-			&uvcg_streaming_grp);
-
-	config_group_init_type_name(&opts->func_inst.group,
-			"",
-			&uvc_func_type);
-	configfs_add_default_group(&uvcg_control_grp,
-			&opts->func_inst.group);
-	configfs_add_default_group(&uvcg_streaming_grp,
-			&opts->func_inst.group);
+	int ret;
 
-	return 0;
+	config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name,
+				    &uvc_func_type.type);
+
+	ret = uvcg_config_create_children(&opts->func_inst.group,
+					  &uvc_func_type);
+	if (ret < 0)
+		config_group_put(&opts->func_inst.group);
+
+	return ret;
 }
]

250/2 2026/07/30 14:39 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 76743
							output: 26
							thoughts: 116
						

Thoughts:
**Delving into the `uvcg_config_remove_children` Implementation**

Okay, so it clicked! `uvcg_config_remove_children`, that method, the one introduced in `efbf0af70b4f`, was all about the group allocation strategy. It seems like the switch from static groups to dynamically allocated ones necessitated a cleanup mechanism. Makes perfect sense. Dynamic allocation, dynamic deallocation – you have to manage those resources, and you have to free them when you're done with them.

Initially, I suspected `configfs_remove_default_groups` wasn't accessible or perhaps not applicable here. That's why they likely rolled their own solution. But wait a second, let me rethink...wasn't that function *exported*? Let's verify, just to be absolutely sure. Okay, I'll need to check the source code in `fs/configfs/dir.c`. I need to ensure my assumptions are all correct.



251/2 2026/07/30 14:39 tool grepper
0m Args:
map[Expression:EXPORT_SYMBOL.*configfs_remove_default_groups]

Results:
map[Output:fs/configfs/dir.c=748=void configfs_remove_default_groups(struct config_group *group)
--
fs/configfs/dir.c-756-}
fs/configfs/dir.c:757:EXPORT_SYMBOL(configfs_remove_default_groups);
fs/configfs/dir.c-758-
]

252/2 2026/07/30 14:39 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 77193
							output: 40
							thoughts: 73
						

Thoughts:
**Examining the ConfigFS Removal Logic**

Okay, so the system *does* export, that much is clear. However, I'm digging into the lower levels of this `uvc_configfs.c` file and I've noticed something. The folks who wrote this implemented their own `uvcg_config_remove_children` function specifically to handle the recursive removal of children. Interesting.

That's a bit of a red flag; why implement custom recursive behavior when ConfigFS offers core functionality? Then it hits me, I need to double-check that `configfs_remove_default_groups`. Wait, maybe I'm misremembering its function. Let me go back and give it a thorough once-over, to verify the recursive behavior (or lack thereof). This discrepancy is important for the overall design.



253/2 2026/07/30 14:39 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_remove_default_groups]

Results:
map[SourceCode: 748:	void configfs_remove_default_groups(struct config_group *group)
 749:	{
 750:		struct config_group *g, *n;
 751:	
 752:		list_for_each_entry_safe(g, n, &group->default_groups, group_entry) {
 753:			list_del(&g->group_entry);
 754:			config_item_put(&g->cg_item);
 755:		}
 756:	}
 SourceFile:fs/configfs/dir.c]

254/2 2026/07/30 14:39 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 77652
							output: 35
							thoughts: 576
						

Thoughts:
**My Analysis of the `configfs_remove_default_groups` Bug and Past Fixes**

Okay, so I've got this bug where `configfs_remove_default_groups` isn't fully removing nested default groups. I see that it only removes direct children and doesn't cascade down. But if you call it on the parent, the refcount of the child drops. If the refcount goes to zero, the child's `release` function is called. And, aha! If that `release` function then *itself* calls `configfs_remove_default_groups` on *its* children, we get the recursive cleanup we need. The bug report outlines this perfectly: the fix drops the default groups in a cascading fashion within the `release` functions of nested configfs instances. This confirms my understanding.

Now, the task is to find similar fixes in the USB gadget subsystem. Initially, I thought there were no relevant commits using `configfs_remove_default_groups` directly within `drivers/usb/gadget/`. However, I need to broaden my search and think conceptually. Ah-ha! I've found something! While it's not a direct call to `configfs_remove_default_groups`, `uvcg_config_remove_children` from the commit `efbf0af70b4f` ("usb: gadget: uvc: configfs: Allocate groups dynamically") is essentially doing the *same thing*! It's recursively removing and dropping refcounts of dynamically allocated default groups. This is the same pattern of nested release functions calling their own group removal. This is exactly what I was looking for!

So, the pattern is:

1.  Identify the need for recursive cleanup of dynamically allocated default groups within the configfs structure.
2.  In the `release` function, call the cleanup function that removes all default groups.
3.  The cleanup function should call `configfs_remove_default_groups` on all child nodes, which will trigger their `release` functions and cascading cleanup.

I also checked other recent additions like `f_midi2.c` and older files like `f_mass_storage.c` for similar issues to see if there were more fixes I could leverage for guidance, so I would have a holistic understanding of how to address and avoid such bugs in the future, however, I found that the `uvcg_config_remove_children` pattern should be sufficient to write a fix for this bug.



255/2 2026/07/30 14:39 tool git-log
0m Args:
map[Count:1 PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:224fb8661f66 usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
]

256/2 2026/07/30 14:39 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 78834
							output: 27
							thoughts: 63
						

Thoughts:
**Investigating the Origin of `f_midi2.c`**

Okay, so I need to trace the introduction of `f_midi2.c`. The first thing that jumps to mind is that it was likely introduced in the commit `01037389c23f`, which seems to be titled "usb: gadget: Add UMP / MIDI 2.0 gadget driver." I'll need to confirm that this is indeed the commit where the file was added. Time to delve into the details of that commit and see what I can find.



257/2 2026/07/30 14:39 tool git-show
0m Error:
git show failed: fatal: Not a valid object name 01037389c23f^{commit}

Args:
map[Commit:01037389c23f]

Results:
map[Output:]

258/2 2026/07/30 14:39 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 79085
							output: 32
							thoughts: 34
						

Thoughts:
Okay, here's my thought process as if I were considering the scenario:

**Finding That Specific Commit**

Hmm, I need to find that specific commit, but I'm drawing a blank on the exact hash right now. No worries, I'll take a targeted approach. Let me see... I'll search for the relevant keywords to jog my memory and narrow down the possibilities. Okay, let's try searching for something like "usb: gadget: Add UMP / MIDI 2.0 gadget driver". That should be a pretty specific and unique enough search term that it will hopefully surface the commit I'm after, or at least a manageable set of results that I can quickly scan. This approach should get me back on track pretty quickly.



259/2 2026/07/30 14:40 tool git-log
0m Args:
map[MessageRegexps:[usb: gadget: Add UMP / MIDI 2.0 gadget driver]]

Results:
map[Output:]

260/2 2026/07/30 14:40 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 79321
							output: 36
							thoughts: 16
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into the `f_midi2.c` History**

Okay, first things first, let's take a look at the commit history for `f_midi2.c`. I need to get a clear picture of the evolution of this module. Understanding the chronological changes is key before I can even begin to assess its current state or potential for modifications. I'm thinking I'll start with the standard `git log` commands, maybe `--graph` to visualize branching. I'll probably also add in some filters like `--author=` if I'm specifically looking for work done by certain contributors, or `--since=` and `--until=` if I want to focus on a particular timeframe. This should give me a solid foundation.



261/2 2026/07/30 14:40 tool git-log
0m Args:
map[Count:10 PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:224fb8661f66 usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
189f164e573e Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
32a92f8c8932 Convert more 'alloc_obj' cases to default GFP_KERNEL arguments
bf4afc53b77a Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
69050f8d6d07 treewide: Replace kmalloc with kmalloc_obj for non-scalar types
e715bc42e337 usb: gadget: Constify struct configfs_item_operations and configfs_group_operations
116e79c679a1 usb: gadget: midi2: Fix MIDI2 IN EP max packet size
21d8525d2e06 usb: gadget: midi2: Fix missing UMP group attributes initialization
dd33993a9721 ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info
82937056967d usb: gadget: midi2: Fix interpretation of is_midi1 bits
]

262/2 2026/07/30 14:40 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 79846
							output: 36
							thoughts: 7
						

Thoughts:
Okay, I'm ready to dive into that text! I'll approach this as if these are *my* thoughts, as an expert in my field, distilling the essence and focusing on what matters most.

**Initial Considerations and Direction**

Alright, the initial prompt is simple enough. It's time to gather more information, to dig deeper into the context. This "Let's get more history" indicates a desire for a more comprehensive understanding. It's a call for the foundational background knowledge, whatever that history may entail. It suggests that a superficial understanding won't suffice; we need depth and context to proceed effectively. My mind is already starting to formulate the key questions: What domain are we in? What historical events or factors are relevant? What's the specific question we're trying to answer, and how does this history inform that?



263/2 2026/07/30 14:40 tool git-log
0m Args:
map[Count:20 PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:224fb8661f66 usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
189f164e573e Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
32a92f8c8932 Convert more 'alloc_obj' cases to default GFP_KERNEL arguments
bf4afc53b77a Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
69050f8d6d07 treewide: Replace kmalloc with kmalloc_obj for non-scalar types
e715bc42e337 usb: gadget: Constify struct configfs_item_operations and configfs_group_operations
116e79c679a1 usb: gadget: midi2: Fix MIDI2 IN EP max packet size
21d8525d2e06 usb: gadget: midi2: Fix missing UMP group attributes initialization
dd33993a9721 ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info
82937056967d usb: gadget: midi2: Fix interpretation of is_midi1 bits
7f72d17359e5 usb: gadget: function: remove redundant else statement
d9c61bb33fbb usb: gadget: function: move u_f.h to include/linux/usb/func_utils.h
228a953e61d6 usb: gadget: midi2: Fix the response for FB info with block 0xff
3eb27d3e32c7 usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
1cb9ba5e61e8 usb: gadget: add missing MODULE_DESCRIPTION() macros
46decc82ffd5 usb: gadget: unconditionally allocate hs/ss descriptor in bind operation
6bb75eb9ff3a usb: gadget: midi2: fix missing unlock in f_midi2_block_opts_create()
a85ff0db48c3 usb: gadget: midi2: More flexible MIDI 1.0 configuration
1b437d2fb3c1 usb: gadget: midi2: Add "Operation Mode" control
d6468be779af usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
]

264/2 2026/07/30 14:40 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 80641
							output: 37
							thoughts: 16
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Initial Commit Thoughts: `f_midi2.c`**

Okay, time to kick things off. Let's get that first commit of `f_midi2.c` in the bag. I'm thinking clean, minimal, and functional – we can always iterate, but a solid foundation is crucial. The goal is a buildable structure first. We'll outline the basic components and ensure they compile cleanly. This initial commit needs to reflect a coherent, if minimal, design. Think header inclusion, any essential typedefs, maybe even stubs for the core functions to signal what's planned. I should also consider how to make it easy to extend for future additions. I need to keep the architecture of this library in mind as I begin, especially any existing interfaces I need to use, and any future ones I need to create.



265/2 2026/07/30 14:40 tool git-log
0m Args:
map[Count:100 PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:224fb8661f66 usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
189f164e573e Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
32a92f8c8932 Convert more 'alloc_obj' cases to default GFP_KERNEL arguments
bf4afc53b77a Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
69050f8d6d07 treewide: Replace kmalloc with kmalloc_obj for non-scalar types
e715bc42e337 usb: gadget: Constify struct configfs_item_operations and configfs_group_operations
116e79c679a1 usb: gadget: midi2: Fix MIDI2 IN EP max packet size
21d8525d2e06 usb: gadget: midi2: Fix missing UMP group attributes initialization
dd33993a9721 ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info
82937056967d usb: gadget: midi2: Fix interpretation of is_midi1 bits
7f72d17359e5 usb: gadget: function: remove redundant else statement
d9c61bb33fbb usb: gadget: function: move u_f.h to include/linux/usb/func_utils.h
228a953e61d6 usb: gadget: midi2: Fix the response for FB info with block 0xff
3eb27d3e32c7 usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
1cb9ba5e61e8 usb: gadget: add missing MODULE_DESCRIPTION() macros
46decc82ffd5 usb: gadget: unconditionally allocate hs/ss descriptor in bind operation
6bb75eb9ff3a usb: gadget: midi2: fix missing unlock in f_midi2_block_opts_create()
a85ff0db48c3 usb: gadget: midi2: More flexible MIDI 1.0 configuration
1b437d2fb3c1 usb: gadget: midi2: Add "Operation Mode" control
d6468be779af usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
856fa444b098 usb: gadget: midi2: Dynamically create MIDI 1.0 altset descriptors
29ee7a4dddd5 usb: gadget: midi2: Add configfs support
8b645922b223 usb: gadget: Add support for USB MIDI 2.0 function driver
]

266/2 2026/07/30 14:40 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 81540
							output: 24
							thoughts: 34
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Analyzing the ConfigFS Integration**

Right, so `29ee7a4dddd5`—that's the commit ID, right? I immediately recognize that one: configfs support. Good. Always interested to see how that's being integrated. Let me pull that up. I need to dive into `29ee7a4dddd5` and see precisely what they've done. I'm keen to understand the nuances of this implementation. Things to consider: how well have they handled the security implications of exposing this interface? Is there proper error handling in place, or are they leaving that to a higher level? Did they consider existing frameworks, or is it a new custom implementation? A thorough review is in order. Let's get to it.



267/2 2026/07/30 14:40 tool git-show
0m Args:
map[Commit:29ee7a4dddd5]

Results:
map[Output:commit 29ee7a4dddd5caa18d1cef000f20c6af43f762f1
Author: Takashi Iwai <tiwai@suse.de>
Date:   Tue Jul 25 08:22:01 2023 +0200

    usb: gadget: midi2: Add configfs support
    
    This patch adds the support of configfs to MIDI 2.0 function driver
    for users to allow configuring the UMP Endpoint and Function Blocks
    more flexibly.  The configuration is in a tree form.  The top-most
    contains some card-level configurations.  UMP Endpoints are defined in
    subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
    configurations such as ep_name, etc.  And, UMP Function Blocks are
    defined in the subdirectories (block.0, block.1, etc) under EP
    subdirectory.  As default, the driver creates a single UMP Endpoint
    (ep.0) and a single Function Block (block.0) to work in a minimalistic
    manner.  User can modify those attributes freely to fit with the
    demands.
    
    When multiple Function Blocks are required, user can create another
    directory as block.1, block.2, and so on (up to block.31).  A block.*
    directory can be deleted dynamically, too.  A caveat is that the block
    number has to be continuous.
    
    Similarly, when multiple UMP Endpoints are required, user can create
    another directory as ep.1, ep.2, up to ep.3.
    
    Also, some driver behavior can be controlled in the card top-level
    configs.  e.g. you can pass process_ump=0 to disable the processing of
    UMP Stream messages.  This would be equivalent with the older MIDI 2.0
    spec that doesn't support UMP v1.1 features.
    
    The configfs interface checks upper- / lower-bound of input values,
    and more sanity checks are performed at binding.
    
    Attributes can't be changed any longer once when the instance is
    linked to UDC.
    
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-midi2 b/Documentation/ABI/testing/configfs-usb-gadget-midi2
new file mode 100644
index 000000000000..a3a036d784c7
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-usb-gadget-midi2
@@ -0,0 +1,52 @@
+What:		/config/usb-gadget/gadget/functions/midi2.name
+Date:		Jul 2023
+KernelVersion:	6.6
+Description:
+		The attributes:
+
+		============	===============================================
+		process_ump	Flag to process UMP Stream messages (0 or 1)
+		static_block	Flag for static blocks (0 or 1)
+		iface_name	MIDI interface name string
+		============	===============================================
+
+What:		/config/usb-gadget/gadget/functions/midi2.name/ep.number
+Date:		Jul 2023
+KernelVersion:	6.6
+Description:
+		This group contains a UMP Endpoint configuration.
+		A new Endpoint starts from 0, and can be up to 3.
+
+		The attributes:
+
+		=============	===============================================
+		protocol_caps	MIDI protocol capabilities (1, 2 or 3 for both)
+		protocol	Default MIDI protocol (1 or 2)
+		ep_name		UMP Endpoint name string
+		product_id	Product ID string
+		manufacturer	Manufacture ID (24 bit)
+		family		Device family ID (16 bit)
+		model		Device model ID (16 bit)
+		sw_revision	Software Revision (32 bit)
+		=============	===============================================
+
+What:		/config/usb-gadget/gadget/functions/midi2.name/ep.number/block.number
+Date:		Jul 2023
+KernelVersion:	6.6
+Description:
+		This group contains a UMP Function Block configuration.
+		A new block starts from 0, and can be up to 31.
+
+		The attributes:
+
+		===============	===============================================
+		name		Function Block name string
+		direction	1: input, 2: output, 3: bidirectional
+		first_group	The first UMP Group number (0-15)
+		num_groups	The number of groups in this FB (1-16)
+		ui_hint		0: unknown, 1: receiver, 2: sender, 3: both
+		midi_ci_verison	Supported MIDI-CI version number (8 bit)
+		is_midi1	Legacy MIDI 1.0 device (0, 1 or 2)
+		sysex8_streams	Max number of SysEx8 streams (8 bit)
+		active		Active FB flag (0 or 1)
+		===============	===============================================
diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 848cb3150deb..c68a6fa0d237 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -292,7 +292,7 @@ static struct usb_interface_descriptor midi2_midi2_if_desc = {
 	.bDescriptorType =	USB_DT_INTERFACE,
 	.bInterfaceNumber =	0, // to be filled
 	.bAlternateSetting =	1,
-	.bNumEndpoints =	2,
+	.bNumEndpoints =	2, // to be filled
 	.bInterfaceClass =	USB_CLASS_AUDIO,
 	.bInterfaceSubClass =	USB_SUBCLASS_MIDISTREAMING,
 	.bInterfaceProtocol =	0,
@@ -1403,6 +1403,8 @@ static int f_midi2_bind(struct usb_configuration *c, struct usb_function *f)
 				midi2->strings[gtb_to_str_id(ep->blks[blk].gtb_id)].id;
 	}
 
+	midi2_midi2_if_desc.bNumEndpoints = midi2->num_eps * 2;
+
 	/* audio interface */
 	status = usb_interface_id(c, f);
 	if (status < 0)
@@ -1510,16 +1512,274 @@ static void f_midi2_unbind(struct usb_configuration *c, struct usb_function *f)
 	usb_free_all_descriptors(f);
 }
 
+/*
+ * ConfigFS interface
+ */
+
+/* type conversion helpers */
+static inline struct f_midi2_opts *to_f_midi2_opts(struct config_item *item)
+{
+	return container_of(to_config_group(item), struct f_midi2_opts,
+			    func_inst.group);
+}
+
+static inline struct f_midi2_ep_opts *
+to_f_midi2_ep_opts(struct config_item *item)
+{
+	return container_of(to_config_group(item), struct f_midi2_ep_opts,
+			    group);
+}
+
+static inline struct f_midi2_block_opts *
+to_f_midi2_block_opts(struct config_item *item)
+{
+	return container_of(to_config_group(item), struct f_midi2_block_opts,
+			    group);
+}
+
+/* trim the string to be usable for EP and FB name strings */
+static void make_name_string(char *s)
+{
+	char *p;
+
+	p = strchr(s, '\n');
+	if (p)
+		*p = 0;
+
+	p = s + strlen(s);
+	for (; p > s && isspace(*p); p--)
+		*p = 0;
+}
+
+/* configfs helpers: generic show/store for unisnged int */
+static ssize_t f_midi2_opts_uint_show(struct f_midi2_opts *opts,
+				      u32 val, const char *format, char *page)
+{
+	int result;
+
+	mutex_lock(&opts->lock);
+	result = sprintf(page, format, val);
+	mutex_unlock(&opts->lock);
+	return result;
+}
+
+static ssize_t f_midi2_opts_uint_store(struct f_midi2_opts *opts,
+				       u32 *valp, u32 minval, u32 maxval,
+				       const char *page, size_t len)
+{
+	int ret;
+	u32 val;
+
+	mutex_lock(&opts->lock);
+	if (opts->refcnt) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	ret = kstrtou32(page, 0, &val);
+	if (ret)
+		goto end;
+	if (val < minval || val > maxval) {
+		ret = -EINVAL;
+		goto end;
+	}
+
+	*valp = val;
+	ret = len;
+
+end:
+	mutex_unlock(&opts->lock);
+	return ret;
+}
+
+/* generic store for bool */
+static ssize_t f_midi2_opts_bool_store(struct f_midi2_opts *opts,
+				       bool *valp, const char *page, size_t len)
+{
+	int ret;
+	bool val;
+
+	mutex_lock(&opts->lock);
+	if (opts->refcnt) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	ret = kstrtobool(page, &val);
+	if (ret)
+		goto end;
+	*valp = val;
+	ret = len;
+
+end:
+	mutex_unlock(&opts->lock);
+	return ret;
+}
+
+/* generic show/store for string */
+static ssize_t f_midi2_opts_str_show(struct f_midi2_opts *opts,
+				     const char *str, char *page)
+{
+	int result = 0;
+
+	mutex_lock(&opts->lock);
+	if (str)
+		result = scnprintf(page, PAGE_SIZE, "%s\n", str);
+	mutex_unlock(&opts->lock);
+	return result;
+}
+
+static ssize_t f_midi2_opts_str_store(struct f_midi2_opts *opts,
+				      const char **strp, size_t maxlen,
+				      const char *page, size_t len)
+{
+	char *c;
+	int ret;
+
+	mutex_lock(&opts->lock);
+	if (opts->refcnt) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	c = kstrndup(page, min(len, maxlen), GFP_KERNEL);
+	if (!c) {
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	kfree(*strp);
+	make_name_string(c);
+	*strp = c;
+	ret = len;
+
+end:
+	mutex_unlock(&opts->lock);
+	return ret;
+}
+
+/*
+ * Definitions for UMP Block config
+ */
+
+/* define an uint option for block */
+#define F_MIDI2_BLOCK_OPT(name, format, minval, maxval)			\
+static ssize_t f_midi2_block_opts_##name##_show(struct config_item *item,\
+					  char *page)			\
+{									\
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);	\
+	return f_midi2_opts_uint_show(opts->ep->opts, opts->info.name,	\
+				      format "\n", page);		\
+}									\
+									\
+static ssize_t f_midi2_block_opts_##name##_store(struct config_item *item,\
+					 const char *page, size_t len)	\
+{									\
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);	\
+	return f_midi2_opts_uint_store(opts->ep->opts, &opts->info.name,\
+				       minval, maxval, page, len);	\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_block_opts_, name)
+
+/* define a boolean option for block */
+#define F_MIDI2_BLOCK_BOOL_OPT(name)					\
+static ssize_t f_midi2_block_opts_##name##_show(struct config_item *item,\
+					  char *page)			\
+{									\
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);	\
+	return f_midi2_opts_uint_show(opts->ep->opts, opts->info.name,	\
+				      "%u\n", page);			\
+}									\
+									\
+static ssize_t f_midi2_block_opts_##name##_store(struct config_item *item,\
+					 const char *page, size_t len)	\
+{									\
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);	\
+	return f_midi2_opts_bool_store(opts->ep->opts, &opts->info.name,\
+				       page, len);			\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_block_opts_, name)
+
+F_MIDI2_BLOCK_OPT(direction, "0x%x", 1, 3);
+F_MIDI2_BLOCK_OPT(first_group, "0x%x", 0, 15);
+F_MIDI2_BLOCK_OPT(num_groups, "0x%x", 1, 16);
+F_MIDI2_BLOCK_OPT(ui_hint, "0x%x", 0, 3);
+F_MIDI2_BLOCK_OPT(midi_ci_version, "%u", 0, 1);
+F_MIDI2_BLOCK_OPT(sysex8_streams, "%u", 0, 255);
+F_MIDI2_BLOCK_OPT(is_midi1, "%u", 0, 2);
+F_MIDI2_BLOCK_BOOL_OPT(active);
+
+static ssize_t f_midi2_block_opts_name_show(struct config_item *item,
+					    char *page)
+{
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
+
+	return f_midi2_opts_str_show(opts->ep->opts, opts->info.name, page);
+}
+
+static ssize_t f_midi2_block_opts_name_store(struct config_item *item,
+					     const char *page, size_t len)
+{
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
+
+	return f_midi2_opts_str_store(opts->ep->opts, &opts->info.name, 128,
+				      page, len);
+}
+
+CONFIGFS_ATTR(f_midi2_block_opts_, name);
+
+static struct configfs_attribute *f_midi2_block_attrs[] = {
+	&f_midi2_block_opts_attr_direction,
+	&f_midi2_block_opts_attr_first_group,
+	&f_midi2_block_opts_attr_num_groups,
+	&f_midi2_block_opts_attr_ui_hint,
+	&f_midi2_block_opts_attr_midi_ci_version,
+	&f_midi2_block_opts_attr_sysex8_streams,
+	&f_midi2_block_opts_attr_is_midi1,
+	&f_midi2_block_opts_attr_active,
+	&f_midi2_block_opts_attr_name,
+	NULL,
+};
+
+static void f_midi2_block_opts_release(struct config_item *item)
+{
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
+
+	kfree(opts->info.name);
+	kfree(opts);
+}
+
+static struct configfs_item_operations f_midi2_block_item_ops = {
+	.release	= f_midi2_block_opts_release,
+};
+
+static const struct config_item_type f_midi2_block_type = {
+	.ct_item_ops	= &f_midi2_block_item_ops,
+	.ct_attrs	= f_midi2_block_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
 /* create a f_midi2_block_opts instance for the given block number */
 static int f_midi2_block_opts_create(struct f_midi2_ep_opts *ep_opts,
 				     unsigned int blk,
 				     struct f_midi2_block_opts **block_p)
 {
 	struct f_midi2_block_opts *block_opts;
+	int ret = 0;
+
+	mutex_lock(&ep_opts->opts->lock);
+	if (ep_opts->opts->refcnt || ep_opts->blks[blk]) {
+		ret = -EBUSY;
+		goto out;
+	}
 
 	block_opts = kzalloc(sizeof(*block_opts), GFP_KERNEL);
-	if (!block_opts)
-		return -ENOMEM;
+	if (!block_opts) {
+		ret = -ENOMEM;
+		goto out;
+	}
 
 	block_opts->ep = ep_opts;
 	block_opts->id = blk;
@@ -1533,9 +1793,143 @@ static int f_midi2_block_opts_create(struct f_midi2_ep_opts *ep_opts,
 
 	ep_opts->blks[blk] = block_opts;
 	*block_p = block_opts;
-	return 0;
+
+	mutex_unlock(&ep_opts->opts->lock);
+ out:
+	return ret;
 }
 
+/* make_group callback for a block */
+static struct config_group *
+f_midi2_opts_block_make(struct config_group *group, const char *name)
+{
+	struct f_midi2_ep_opts *ep_opts;
+	struct f_midi2_block_opts *block_opts;
+	unsigned int blk;
+	int ret;
+
+	if (strncmp(name, "block.", 6))
+		return ERR_PTR(-EINVAL);
+	ret = kstrtouint(name + 6, 10, &blk);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ep_opts = to_f_midi2_ep_opts(&group->cg_item);
+
+	if (blk >= SNDRV_UMP_MAX_BLOCKS)
+		return ERR_PTR(-EINVAL);
+	if (ep_opts->blks[blk])
+		return ERR_PTR(-EBUSY);
+	ret = f_midi2_block_opts_create(ep_opts, blk, &block_opts);
+	if (ret)
+		return ERR_PTR(ret);
+
+	config_group_init_type_name(&block_opts->group, name,
+				    &f_midi2_block_type);
+	return &block_opts->group;
+}
+
+/* drop_item callback for a block */
+static void
+f_midi2_opts_block_drop(struct config_group *group, struct config_item *item)
+{
+	struct f_midi2_block_opts *block_opts = to_f_midi2_block_opts(item);
+
+	mutex_lock(&block_opts->ep->opts->lock);
+	block_opts->ep->blks[block_opts->id] = NULL;
+	mutex_unlock(&block_opts->ep->opts->lock);
+	config_item_put(item);
+}
+
+/*
+ * Definitions for UMP Endpoint config
+ */
+
+/* define an uint option for EP */
+#define F_MIDI2_EP_OPT(name, format, minval, maxval)			\
+static ssize_t f_midi2_ep_opts_##name##_show(struct config_item *item,	\
+					     char *page)		\
+{									\
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);	\
+	return f_midi2_opts_uint_show(opts->opts, opts->info.name,	\
+				      format "\n", page);		\
+}									\
+									\
+static ssize_t f_midi2_ep_opts_##name##_store(struct config_item *item,	\
+					   const char *page, size_t len)\
+{									\
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);	\
+	return f_midi2_opts_uint_store(opts->opts, &opts->info.name,	\
+				       minval, maxval, page, len);	\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_ep_opts_, name)
+
+/* define a string option for EP */
+#define F_MIDI2_EP_STR_OPT(name, maxlen)				\
+static ssize_t f_midi2_ep_opts_##name##_show(struct config_item *item,	\
+					     char *page)		\
+{									\
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);	\
+	return f_midi2_opts_str_show(opts->opts, opts->info.name, page);\
+}									\
+									\
+static ssize_t f_midi2_ep_opts_##name##_store(struct config_item *item,	\
+					 const char *page, size_t len)	\
+{									\
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);	\
+	return f_midi2_opts_str_store(opts->opts, &opts->info.name, maxlen,\
+				      page, len);			\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_ep_opts_, name)
+
+F_MIDI2_EP_OPT(protocol, "0x%x", 1, 2);
+F_MIDI2_EP_OPT(protocol_caps, "0x%x", 1, 3);
+F_MIDI2_EP_OPT(manufacturer, "0x%x", 0, 0xffffff);
+F_MIDI2_EP_OPT(family, "0x%x", 0, 0xffff);
+F_MIDI2_EP_OPT(model, "0x%x", 0, 0xffff);
+F_MIDI2_EP_OPT(sw_revision, "0x%x", 0, 0xffffffff);
+F_MIDI2_EP_STR_OPT(ep_name, 128);
+F_MIDI2_EP_STR_OPT(product_id, 128);
+
+static struct configfs_attribute *f_midi2_ep_attrs[] = {
+	&f_midi2_ep_opts_attr_protocol,
+	&f_midi2_ep_opts_attr_protocol_caps,
+	&f_midi2_ep_opts_attr_ep_name,
+	&f_midi2_ep_opts_attr_product_id,
+	&f_midi2_ep_opts_attr_manufacturer,
+	&f_midi2_ep_opts_attr_family,
+	&f_midi2_ep_opts_attr_model,
+	&f_midi2_ep_opts_attr_sw_revision,
+	NULL,
+};
+
+static void f_midi2_ep_opts_release(struct config_item *item)
+{
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
+
+	kfree(opts->info.ep_name);
+	kfree(opts->info.product_id);
+	kfree(opts);
+}
+
+static struct configfs_item_operations f_midi2_ep_item_ops = {
+	.release	= f_midi2_ep_opts_release,
+};
+
+static struct configfs_group_operations f_midi2_ep_group_ops = {
+	.make_group	= f_midi2_opts_block_make,
+	.drop_item	= f_midi2_opts_block_drop,
+};
+
+static const struct config_item_type f_midi2_ep_type = {
+	.ct_item_ops	= &f_midi2_ep_item_ops,
+	.ct_group_ops	= &f_midi2_ep_group_ops,
+	.ct_attrs	= f_midi2_ep_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
 /* create a f_midi2_ep_opts instance */
 static int f_midi2_ep_opts_create(struct f_midi2_opts *opts,
 				  unsigned int index,
@@ -1559,7 +1953,119 @@ static int f_midi2_ep_opts_create(struct f_midi2_opts *opts,
 	return 0;
 }
 
+/* make_group callback for an EP */
+static struct config_group *
+f_midi2_opts_ep_make(struct config_group *group, const char *name)
+{
+	struct f_midi2_opts *opts;
+	struct f_midi2_ep_opts *ep_opts;
+	unsigned int index;
+	int ret;
+
+	if (strncmp(name, "ep.", 3))
+		return ERR_PTR(-EINVAL);
+	ret = kstrtouint(name + 3, 10, &index);
+	if (ret)
+		return ERR_PTR(ret);
+
+	opts = to_f_midi2_opts(&group->cg_item);
+	if (index >= MAX_UMP_EPS)
+		return ERR_PTR(-EINVAL);
+	if (opts->eps[index])
+		return ERR_PTR(-EBUSY);
+	ret = f_midi2_ep_opts_create(opts, index, &ep_opts);
+	if (ret)
+		return ERR_PTR(ret);
+
+	config_group_init_type_name(&ep_opts->group, name, &f_midi2_ep_type);
+	return &ep_opts->group;
+}
+
+/* drop_item callback for an EP */
+static void
+f_midi2_opts_ep_drop(struct config_group *group, struct config_item *item)
+{
+	struct f_midi2_ep_opts *ep_opts = to_f_midi2_ep_opts(item);
+
+	mutex_lock(&ep_opts->opts->lock);
+	ep_opts->opts->eps[ep_opts->index] = NULL;
+	mutex_unlock(&ep_opts->opts->lock);
+	config_item_put(item);
+}
+
+/*
+ * Definitions for card config
+ */
+
+/* define a bool option for card */
+#define F_MIDI2_BOOL_OPT(name)						\
+static ssize_t f_midi2_opts_##name##_show(struct config_item *item,	\
+					  char *page)			\
+{									\
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);		\
+	return f_midi2_opts_uint_show(opts, opts->info.name,		\
+				      "%u\n", page);			\
+}									\
+									\
+static ssize_t f_midi2_opts_##name##_store(struct config_item *item,	\
+					 const char *page, size_t len)	\
+{									\
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);		\
+	return f_midi2_opts_bool_store(opts, &opts->info.name,		\
+				       page, len);			\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_opts_, name)
+
+F_MIDI2_BOOL_OPT(process_ump);
+F_MIDI2_BOOL_OPT(static_block);
+
+static ssize_t f_midi2_opts_iface_name_show(struct config_item *item,
+					    char *page)
+{
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);
+
+	return f_midi2_opts_str_show(opts, opts->info.iface_name, page);
+}
+
+static ssize_t f_midi2_opts_iface_name_store(struct config_item *item,
+					     const char *page, size_t len)
+{
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);
+
+	return f_midi2_opts_str_store(opts, &opts->info.iface_name, 128,
+				      page, len);
+}
+
+CONFIGFS_ATTR(f_midi2_opts_, iface_name);
+
+static struct configfs_attribute *f_midi2_attrs[] = {
+	&f_midi2_opts_attr_process_ump,
+	&f_midi2_opts_attr_static_block,
+	&f_midi2_opts_attr_iface_name,
+	NULL
+};
+
+static void f_midi2_opts_release(struct config_item *item)
+{
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);
+
+	usb_put_function_instance(&opts->func_inst);
+}
+
+static struct configfs_item_operations f_midi2_item_ops = {
+	.release	= f_midi2_opts_release,
+};
+
+static struct configfs_group_operations f_midi2_group_ops = {
+	.make_group	= f_midi2_opts_ep_make,
+	.drop_item	= f_midi2_opts_ep_drop,
+};
+
 static const struct config_item_type f_midi2_func_type = {
+	.ct_item_ops	= &f_midi2_item_ops,
+	.ct_group_ops	= &f_midi2_group_ops,
+	.ct_attrs	= f_midi2_attrs,
 	.ct_owner	= THIS_MODULE,
 };
 
@@ -1569,11 +2075,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
-	/* we have only one EP and one FB */
-	if (opts->eps[0]) {
-		kfree(opts->eps[0]->blks[0]);
-		kfree(opts->eps[0]);
-	}
+	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 
@@ -1596,6 +2098,7 @@ static struct usb_function_instance *f_midi2_alloc_inst(void)
 	opts->info.num_reqs = 32;
 	opts->info.req_buf_size = 512;
 
+	/* create the default ep */
 	ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
 	if (ret) {
 		kfree(opts);
@@ -1612,6 +2115,15 @@ static struct usb_function_instance *f_midi2_alloc_inst(void)
 
 	config_group_init_type_name(&opts->func_inst.group, "",
 				    &f_midi2_func_type);
+
+	config_group_init_type_name(&ep_opts->group, "ep.0",
+				    &f_midi2_ep_type);
+	configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
+
+	config_group_init_type_name(&block_opts->group, "block.0",
+				    &f_midi2_block_type);
+	configfs_add_default_group(&block_opts->group, &ep_opts->group);
+
 	return &opts->func_inst;
 }
 
@@ -1630,12 +2142,58 @@ static void f_midi2_free(struct usb_function *f)
 			container_of(f->fi, struct f_midi2_opts, func_inst));
 }
 
+/* verify the parameters set up via configfs;
+ * return the number of EPs or a negative error
+ */
+static int verify_parameters(struct f_midi2_opts *opts)
+{
+	int i, j, num_eps, num_blks;
+	struct f_midi2_ep_info *ep;
+	struct f_midi2_block_info *bp;
+
+	for (num_eps = 0; num_eps < MAX_UMP_EPS && opts->eps[num_eps];
+	     num_eps++)
+		;
+	if (!num_eps) {
+		pr_err("f_midi2: No EP is defined\n");
+		return -EINVAL;
+	}
+
+	num_blks = 0;
+	for (i = 0; i < num_eps; i++) {
+		ep = &opts->eps[i]->info;
+		if (!(ep->protocol_caps & ep->protocol)) {
+			pr_err("f_midi2: Invalid protocol 0x%x (caps 0x%x) for EP %d\n",
+			       ep->protocol, ep->protocol_caps, i);
+			return -EINVAL;
+		}
+
+		for (j = 0; j < SNDRV_UMP_MAX_BLOCKS && opts->eps[i]->blks[j];
+		     j++, num_blks++) {
+			bp = &opts->eps[i]->blks[j]->info;
+			if (bp->first_group + bp->num_groups > SNDRV_UMP_MAX_GROUPS) {
+				pr_err("f_midi2: Invalid group definitions for block %d:%d\n",
+				       i, j);
+				return -EINVAL;
+			}
+		}
+	}
+	if (!num_blks) {
+		pr_err("f_midi2: No block is defined\n");
+		return -EINVAL;
+	}
+
+	return num_eps;
+}
+
 /* gadget alloc callback */
 static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
 {
 	struct f_midi2 *midi2;
 	struct f_midi2_opts *opts;
-	int i;
+	struct f_midi2_ep *ep;
+	struct f_midi2_block *bp;
+	int i, num_eps, blk;
 
 	midi2 = kzalloc(sizeof(*midi2), GFP_KERNEL);
 	if (!midi2)
@@ -1643,6 +2201,12 @@ static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
 
 	opts = container_of(fi, struct f_midi2_opts, func_inst);
 	mutex_lock(&opts->lock);
+	num_eps = verify_parameters(opts);
+	if (num_eps < 0) {
+		mutex_unlock(&opts->lock);
+		kfree(midi2);
+		return ERR_PTR(num_eps);
+	}
 	++opts->refcnt;
 	mutex_unlock(&opts->lock);
 
@@ -1658,17 +2222,20 @@ static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
 	midi2->func.free_func = f_midi2_free;
 
 	midi2->info = opts->info;
+	midi2->num_eps = num_eps;
 
-	/* fixed 1 UMP EP and 1 UMP FB as of now */
-	midi2->num_eps = 1;
-	midi2->midi2_eps[0].info = opts->eps[0]->info;
-	midi2->midi2_eps[0].card = midi2;
-	midi2->midi2_eps[0].num_blks = 1;
-	midi2->midi2_eps[0].blks[0].info = opts->eps[0]->blks[0]->info;
-	midi2->midi2_eps[0].blks[0].gtb_id = 1;
-
-	for (i = 0; i < midi2->num_eps; i++)
-		midi2->total_blocks += midi2->midi2_eps[i].num_blks;
+	for (i = 0; i < num_eps; i++) {
+		ep = &midi2->midi2_eps[i];
+		ep->info = opts->eps[i]->info;
+		ep->card = midi2;
+		for (blk = 0; blk < SNDRV_UMP_MAX_BLOCKS &&
+			     opts->eps[i]->blks[blk]; blk++) {
+			bp = &ep->blks[blk];
+			ep->num_blks++;
+			bp->info = opts->eps[i]->blks[blk]->info;
+			bp->gtb_id = ++midi2->total_blocks;
+		}
+	}
 
 	midi2->string_defs = kcalloc(midi2->total_blocks + 1,
 				     sizeof(*midi2->string_defs), GFP_KERNEL);
@@ -1678,10 +2245,18 @@ static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
 	}
 
 	if (opts->info.iface_name && *opts->info.iface_name)
-		midi2->string_defs[0].s = opts->info.iface_name;
+		midi2->string_defs[STR_IFACE].s = opts->info.iface_name;
 	else
-		midi2->string_defs[0].s = ump_ep_name(&midi2->midi2_eps[0]);
-	midi2->string_defs[1].s = ump_fb_name(&midi2->midi2_eps[0].blks[0].info);
+		midi2->string_defs[STR_IFACE].s = ump_ep_name(&midi2->midi2_eps[0]);
+
+	for (i = 0; i < midi2->num_eps; i++) {
+		ep = &midi2->midi2_eps[i];
+		for (blk = 0; blk < ep->num_blks; blk++) {
+			bp = &ep->blks[blk];
+			midi2->string_defs[gtb_to_str_id(bp->gtb_id)].s =
+				ump_fb_name(&bp->info);
+		}
+	}
 
 	return &midi2->func;
 }
]

268/2 2026/07/30 14:40 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 92115
							output: 44
							thoughts: 530
						

Thoughts:
**Analyzing a Potential ConfigFS Leak in USB Gadget Driver**

Okay, let's break this down. My initial thought is that commit `29ee7a4dddd5` introduced the problem. It added `configfs_add_default_group` for `ep.0` and `block.0` *and* `f_midi2_free_inst`, but crucially, it *didn't* call `configfs_remove_default_groups` in the `f_midi2_free_inst` path. That feels like a likely culprit for a leak.

Now, the prompt wants me to see how *similar* problems were fixed in the past within this subsystem. That means looking for patterns. The focus is "missing locks, incorrect refcounting, or similar error path bugs."

Given the prompt, I'm already mentally searching for situations where default groups were dynamically created and leaked because `configfs_remove_default_groups` wasn't properly called or handled children recursively. I immediately think of `efbf0af70b4f`, since that introduced dynamic allocation of groups and added `uvcg_config_remove_children` to handle their cleanup, exactly what I suspect is going on here. But, wait, that *didn't* fix a bug, it introduced the *mechanism* for the dynamic allocation and cleanup. So it might be related, but not a direct fix for *this* issue.

I need to see if there are other commits fixing a *missing* `configfs_remove_default_groups`. I did a quick search for `configfs_remove_default_groups` within `drivers/usb/gadget/` but came up empty. Expanding my search across the *entire* kernel, I did find `3d2825c8c610` ("fs: dlm: fix configfs memory leak"). That one addressed a memory leak where `configfs_remove_default_groups` didn't free memory if a child lacked a release function. But, in *this* specific case, `f_midi2_ep_type` and `f_midi2_block_type` *do* have release functions. So `configfs_remove_default_groups` *should* clean things up properly here. It seems like the core issue is the missing call to begin with.

Now, just to be thorough, I'm going to search for any other commits in `drivers/usb/gadget/` that mention "configfs" and "leak". It will be good to see if there are any other situations addressed.



269/2 2026/07/30 14:41 tool git-log
0m Args:
map[MessageRegexps:[configfs leak] PathPrefix:drivers/usb/gadget/ Since:10 years]

Results:
map[Output:70a3288a7586 usb: gadget: f_hid: fix refcount leak on error path
86f3daed59bc usb: gadget: uvc: configfs: Drop leaked references to config items
ff74745e6d3d usb: gadget: configfs: Fix memory leak of interface directory data
]

270/2 2026/07/30 14:41 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 93336
							output: 24
							thoughts: 15
						

Thoughts:
Okay, let's dive into this. Here's my take on those thoughts, as if they're mine:

**Checking `86f3daed59bc`**

Right, let's take a look at `86f3daed59bc`.  That looks like a commit hash, doesn't it? Given my expertise, I immediately start running through possibilities. Is it from a repository I'm familiar with? Is this related to a specific project? My mind's already racing, trying to recall relevant contexts. I might have seen this in a log, a build report, or maybe even in a recent email thread. The number alone isn't telling me much, but it *signals* something specific, something worth investigating. My first impulse is to try and pinpoint its origin – is it a local branch? A remote one? And what tools do I have access to that will allow me to track this down efficiently? A quick `git log` lookup sounds like a good starting point. Or, depending on where I saw it, perhaps a more targeted search within the relevant codebase. This could be anything from a critical bug fix to a major feature addition, so it’s essential to approach it with the appropriate level of analysis, and depending on the context in which it was spotted, I might need to consider the level of urgency.



271/2 2026/07/30 14:41 tool git-show
0m Args:
map[Commit:86f3daed59bc]

Results:
map[Output:commit 86f3daed59bceb4fa7981d85e89f63ebbae1d561
Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Date:   Thu Aug 2 00:14:00 2018 +0300

    usb: gadget: uvc: configfs: Drop leaked references to config items
    
    Some of the .allow_link() and .drop_link() operations implementations
    call config_group_find_item() and then leak the reference to the
    returned item. Fix this by dropping those references where needed.
    
    Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
    Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
index dbc95c9558de..8d513cc6fb8c 100644
--- a/drivers/usb/gadget/function/uvc_configfs.c
+++ b/drivers/usb/gadget/function/uvc_configfs.c
@@ -529,6 +529,7 @@ static int uvcg_control_class_allow_link(struct config_item *src,
 unlock:
 	mutex_unlock(&opts->lock);
 out:
+	config_item_put(header);
 	mutex_unlock(su_mutex);
 	return ret;
 }
@@ -564,6 +565,7 @@ static void uvcg_control_class_drop_link(struct config_item *src,
 unlock:
 	mutex_unlock(&opts->lock);
 out:
+	config_item_put(header);
 	mutex_unlock(su_mutex);
 }
 
@@ -2026,6 +2028,7 @@ static int uvcg_streaming_class_allow_link(struct config_item *src,
 unlock:
 	mutex_unlock(&opts->lock);
 out:
+	config_item_put(header);
 	mutex_unlock(su_mutex);
 	return ret;
 }
@@ -2066,6 +2069,7 @@ static void uvcg_streaming_class_drop_link(struct config_item *src,
 unlock:
 	mutex_unlock(&opts->lock);
 out:
+	config_item_put(header);
 	mutex_unlock(su_mutex);
 }
 
]

272/2 2026/07/30 14:41 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 94309
							output: 26
							thoughts: 31
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Diving into `config_group_find_item()`**

Right, this looks like we're digging into the guts of how this configuration system works. Specifically, we're talking about the `config_group_find_item()` function. That's a key piece; it's the mechanism that actually locates a specific configuration item within a group, likely based on some sort of key or identifier. Understanding its behavior is critical for debugging, performance optimization, and general maintenance. I need to be sure I'm crystal clear on this function.

Let's see… looks like we're referencing a specific commit, `ff74745e6d3d`. This is smart. A specific commit means we can pin down *exactly* what state the code was in at that point. Makes the review that much cleaner. I need to understand what this commit did to this specific function - were there bug fixes, new features, or performance improvements? This commit might reveal some subtle but important nuances or design decisions. Time to dive in and understand the changes.



273/2 2026/07/30 14:41 tool git-show
0m Args:
map[Commit:ff74745e6d3d]

Results:
map[Output:commit ff74745e6d3d97a865eda8c1f3fd29c13b79f0cc
Author: Andrew Gabbasov <andrew_gabbasov@mentor.com>
Date:   Sat Sep 30 08:54:52 2017 -0700

    usb: gadget: configfs: Fix memory leak of interface directory data
    
    Kmemleak checking configuration reports a memory leak in
    usb_os_desc_prepare_interf_dir function when rndis function
    instance is freed and then allocated again. For example, this
    happens with FunctionFS driver with RNDIS function enabled
    when "ffs-test" test application is run several times in a row.
    
    The data for intermediate "os_desc" group for interface directories
    is allocated as a single VLA chunk and (after a change of default
    groups handling) is not ever freed and actually not stored anywhere
    besides inside a list of default groups of a parent group.
    
    The fix is to make usb_os_desc_prepare_interf_dir function return
    a pointer to allocated data (as a pointer to the first VLA item)
    instead of (an unused) integer and to make the caller component
    (currently the only one is RNDIS function) responsible for storing
    the pointer and freeing the memory when appropriate.
    
    Fixes: 1ae1602de028 ("configfs: switch ->default groups to a linked list")
    Cc: stable@vger.kernel.org
    Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com>
    Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index a22a892de7b7..aeb9f3c40521 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -1143,11 +1143,12 @@ static struct configfs_attribute *interf_grp_attrs[] = {
 	NULL
 };
 
-int usb_os_desc_prepare_interf_dir(struct config_group *parent,
-				   int n_interf,
-				   struct usb_os_desc **desc,
-				   char **names,
-				   struct module *owner)
+struct config_group *usb_os_desc_prepare_interf_dir(
+		struct config_group *parent,
+		int n_interf,
+		struct usb_os_desc **desc,
+		char **names,
+		struct module *owner)
 {
 	struct config_group *os_desc_group;
 	struct config_item_type *os_desc_type, *interface_type;
@@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
 
 	char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL);
 	if (!vlabuf)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
 	os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
@@ -1184,7 +1185,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
 		configfs_add_default_group(&d->group, os_desc_group);
 	}
 
-	return 0;
+	return os_desc_group;
 }
 EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir);
 
diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h
index 36c468c4f5e9..540d5e92ed22 100644
--- a/drivers/usb/gadget/configfs.h
+++ b/drivers/usb/gadget/configfs.h
@@ -5,11 +5,12 @@
 
 void unregister_gadget_item(struct config_item *item);
 
-int usb_os_desc_prepare_interf_dir(struct config_group *parent,
-				   int n_interf,
-				   struct usb_os_desc **desc,
-				   char **names,
-				   struct module *owner);
+struct config_group *usb_os_desc_prepare_interf_dir(
+		struct config_group *parent,
+		int n_interf,
+		struct usb_os_desc **desc,
+		char **names,
+		struct module *owner);
 
 static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item)
 {
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c
index e1d5853ef1e4..c7c5b3ce1d98 100644
--- a/drivers/usb/gadget/function/f_rndis.c
+++ b/drivers/usb/gadget/function/f_rndis.c
@@ -908,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f)
 			free_netdev(opts->net);
 	}
 
+	kfree(opts->rndis_interf_group);	/* single VLA chunk */
 	kfree(opts);
 }
 
@@ -916,6 +917,7 @@ static struct usb_function_instance *rndis_alloc_inst(void)
 	struct f_rndis_opts *opts;
 	struct usb_os_desc *descs[1];
 	char *names[1];
+	struct config_group *rndis_interf_group;
 
 	opts = kzalloc(sizeof(*opts), GFP_KERNEL);
 	if (!opts)
@@ -940,8 +942,14 @@ static struct usb_function_instance *rndis_alloc_inst(void)
 	names[0] = "rndis";
 	config_group_init_type_name(&opts->func_inst.group, "",
 				    &rndis_func_type);
-	usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
-				       names, THIS_MODULE);
+	rndis_interf_group =
+		usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs,
+					       names, THIS_MODULE);
+	if (IS_ERR(rndis_interf_group)) {
+		rndis_free_inst(&opts->func_inst);
+		return ERR_CAST(rndis_interf_group);
+	}
+	opts->rndis_interf_group = rndis_interf_group;
 
 	return &opts->func_inst;
 }
diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h
index a35ee3c2545d..efdb7ac381d9 100644
--- a/drivers/usb/gadget/function/u_rndis.h
+++ b/drivers/usb/gadget/function/u_rndis.h
@@ -26,6 +26,7 @@ struct f_rndis_opts {
 	bool				bound;
 	bool				borrowed_net;
 
+	struct config_group		*rndis_interf_group;
 	struct usb_os_desc		rndis_os_desc;
 	char				rndis_ext_compat_id[16];
 
]

274/2 2026/07/30 14:41 llm history-explorer
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 96647
							output: 732
							thoughts: 765
						

Thoughts:
**Analyzing the ConfigFS Memory Leak: A Path to the Correct Solution**

Right, I've got it. That commit `ff74745e6d3d` ("usb: gadget: configfs: Fix memory leak of interface directory data") describes *precisely* the situation I'm looking at. The message outlines a scenario where data for an "os_desc" group within an interface directory was being allocated as a VLA chunk and never freed because the default group handling changed, and the memory wasn't being managed properly.

They fixed it by manually freeing the memory of the default group (`kfree(opts->rndis_interf_group);`) directly. My initial thought was: Why didn't they use `configfs_remove_default_groups()`? Ah, because `configfs_remove_default_groups()` drops the refcount and calls the release function. However, the `os_desc` group *didn't* have a release function! In their situation, if there wasn't a release function, then `configfs_remove_default_groups()` *wouldn't* free the memory, so the manual `kfree()` was the right solution.

But, here's the crucial difference: in *our* case, `f_midi2_ep_type` and `f_midi2_block_type` *do* have `release` functions! So the correct fix for *us* is to use `configfs_remove_default_groups()`.

Let's break down what I've discovered:

1.  The core issue is that dynamically allocated configfs default groups aren't automatically freed when their parent is removed because their reference counts aren't dropped.
2.  I've found similar bugs fixed in two primary ways:
    a.  Manually removing the default groups and dropping refcounts. An example is commit `efbf0af70b4f` ("usb: gadget: uvc: configfs: Allocate groups dynamically"). Here, `uvcg_config_remove_children()` was introduced to manually iterate through `default_groups`, remove them from the list, and call `config_item_put()` recursively.
    b.  Manually freeing the memory of the default groups. Commit `ff74745e6d3d` ("usb: gadget: configfs: Fix memory leak of interface directory data") is one such example. The `os_desc` default group memory was freed with `kfree()` within the parent's release function because the group lacked a configfs release function.
3.  I've also seen a similar issue, outside the USB gadget space, in `3d2825c8c610` ("fs: dlm: fix configfs memory leak"), where memory was manually freed in the parent's release function.
4.  Crucially, because `f_midi2_ep_type` and `f_midi2_block_type` already have `release` functions (`f_midi2_ep_opts_release` and `f_midi2_block_opts_release`), the right approach here is to call `configfs_remove_default_groups()` in the parent's release function. This will reduce the refcounts of the default groups, which in turn invokes their respective release functions. These will free the memory correctly, and we'll avoid any need for manual list manipulation or direct calls to `kfree()` on child objects. That's the key to resolving this memory leak!



275/1 2026/07/30 14:41 action kernel-scratch-checkouter
0m Results:
map[KernelScratchSrc:/app/workdir/cache/tmp/tmp1348468677]

276/1 2026/07/30 14:41 loop
23m
277/2 2026/07/30 14:41 iteration 0
23m
278/3 2026/07/30 14:41 agent patch-generator
3m Model:
best-expensive

Instruction:
You are an experienced Linux kernel developer tasked with creating a fix for a kernel bug.
You will be given a crash report, an initial explanation of the root cause done by another
kernel expert, and a summary of how similar bugs were fixed in the past.

Use the codeeditor tool to do code edits.
Note: you will not see your changes when looking at the code using codesearch tools.
Use the patch-diff tool to review the modifications you applied.

Your final reply should contain explanation of what you did in the patch and why
(details not present in the initial explanation of the bug).

Your fix must not just prevent the given crash, but also be the best fix for the underlying
root cause from the software engineering point of view. There can be several ways to fix the
same bug. Consider alternatives, and pick the best one. For example, additional checks may be
added at different locations/functions, it's usually better to place them earlier in the
execution to avoid multiple checks at various locations later.

Frequently the same coding mistake is done in several locations in the source code.
Check if your fix should be extended/applied to similar cases around to fix other similar bugs.
But don't go too wide, don't try to fix problems kernel-wide, fix similar issues
in the same file only.


If you are changing post-conditions of a function, consider all callers of the functions,
and if they need to be updated to handle new post-conditions. For example, if you make
a function that previously never returned a NULL, return NULL, consider if callers
need to be updated to handle NULL return value.



Prefer calling several tools at the same time to save round-trips.

Prompt:
The crash that corresponds to the bug is:

2026/07/30 13:30:35 executed programs: 5
BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504 [inline]
    f_midi2_alloc_inst+0x80/0x2c0 drivers/usb/gadget/function/f_midi2.c:2666
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342 [inline]
    f_midi2_alloc_inst+0x16a/0x2c0 drivers/usb/gadget/function/f_midi2.c:2673
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF


The explanation of the root cause of the bug is:

The root cause of this memory leak is that the driver fails to drop the reference counts of its default configfs groups when the parent group is destroyed.

When a USB function instance for `midi2` is allocated via `f_midi2_alloc_inst()`, it dynamically allocates `ep_opts` and `block_opts` structures using `kzalloc_obj()`. These structures are then initialized as configfs groups and added as default groups to their respective parents:
- `ep.0` is added as a default group to the function instance group (`opts->func_inst.group`).
- `block.0` is added as a default group to the endpoint group (`ep_opts->group`).

When the user removes the configfs directory for the function instance (via `rmdir`), configfs removes the dentries for the default groups but **does not** automatically drop their reference counts. The responsibility of dropping the refcounts of default groups lies with the driver, typically by calling `configfs_remove_default_groups()` when the parent group is released.

However, `f_midi2_free_inst()` (which is called when the function instance's refcount reaches 0) only frees the `f_midi2_opts` structure and does not clean up its default groups. Similarly, `f_midi2_ep_opts_release()` does not clean up its default groups. As a result, the `ep_opts` and `block_opts` structures are leaked.

### How to fix it

To fix the leak, you need to explicitly remove the default groups and drop their reference counts before freeing the parent structures. This can be done by calling `configfs_remove_default_groups()` in the respective release functions.

1. In `f_midi2_free_inst()`, drop the default groups of the function instance (this will drop the refcount of `ep.0` and trigger `f_midi2_ep_opts_release`):
```c
static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group); /* ADD THIS */
	kfree(opts->info.iface_name);
	kfree(opts);
}
```

2. In `f_midi2_ep_opts_release()`, drop the default groups of the endpoint (this will drop the refcount of `block.0` and trigger `f_midi2_block_opts_release`):
```c
static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item)); /* ADD THIS */
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
}
```

With these changes, the hierarchy of default groups will be properly unrolled and freed when the function instance is destroyed, whether it's through configfs `rmdir` or an error path that directly calls `usb_put_function_instance()`.


Historical context on how similar bugs were fixed in the past:

Based on the historical research of similar bugs in the kernel, here is a summary of the findings and the recommended patterns for fixing this issue.

### Findings

The root cause of the bug is that dynamically allocated configfs default groups are not automatically cleaned up when their parent is destroyed. While configfs removes the dentries, it does not automatically drop the reference counts of the default groups. If the driver does not explicitly drop these references, the configfs items (and their dynamically allocated memory) will leak.

In the past, similar issues in the USB gadget subsystem and other configfs users were addressed using two main patterns:

1. **Manually dropping references recursively:**
   In commit `efbf0af70b4f` ("usb: gadget: uvc: configfs: Allocate groups dynamically"), the UVC gadget driver was refactored to dynamically allocate its configfs groups. To prevent memory leaks, the developers introduced a custom `uvcg_config_remove_children()` function. This function manually iterates over the `default_groups` list of a parent, removes each child from the list, recursively cleans up the child's children, and finally calls `config_item_put()` to drop the reference count and trigger the release function.

2. **Manually freeing the child's memory in the parent's release function:**
   In commit `ff74745e6d3d` ("usb: gadget: configfs: Fix memory leak of interface directory data"), a memory leak of the `os_desc` default group in the RNDIS function was fixed. Because the `os_desc` group did not have a dedicated configfs `release` callback, the developers fixed the leak by saving a pointer to the dynamically allocated group and explicitly calling `kfree()` on it inside the parent's release function (`rndis_free_inst`). 
   A similar fix was applied outside the USB subsystem in commit `3d2825c8c610` ("fs: dlm: fix configfs memory leak"), where a default group's memory was manually freed in the parent's release function because `configfs_remove_default_groups()` alone wouldn't free the memory without a release callback.

### Recommended Fix Strategy

For the `f_midi2` bug, the proposed fix of calling `configfs_remove_default_groups()` is the most idiomatic and robust approach. 

Unlike the RNDIS or DLM bugs mentioned above, the `ep.0` and `block.0` groups in `f_midi2` **already have** proper configfs release callbacks implemented (`f_midi2_ep_opts_release` and `f_midi2_block_opts_release` respectively), which correctly call `kfree()`. 

Therefore, you do not need to manually `kfree()` the child structures or write a custom recursive cleanup function like UVC did. You should follow the pattern of explicitly unrolling the default groups by calling `configfs_remove_default_groups()` in the respective parent's release functions:
- Call it in `f_midi2_free_inst()` to drop the refcount of `ep.0`.
- Call it in `f_midi2_ep_opts_release()` to drop the refcount of `block.0`.

This will correctly drop the reference counts, trigger the existing release callbacks, and safely free the dynamically allocated memory in the correct order.




Reply:
I have implemented the fix for the memory leak in the `f_midi2` USB gadget function driver.

### What I did
I added calls to `configfs_remove_default_groups()` in the release functions of the configfs groups that have default groups attached to them:
1. In `f_midi2_free_inst()`, I added `configfs_remove_default_groups(&opts->func_inst.group);` to drop the reference count of the default `ep.0` group.
2. In `f_midi2_ep_opts_release()`, I added `configfs_remove_default_groups(to_config_group(item));` to drop the reference count of the default `block.0` group.

### Why I did it
When a USB function instance for `midi2` is allocated, it dynamically allocates `ep_opts` and `block_opts` structures and adds them as default groups (`ep.0` and `block.0`). While configfs removes the dentries for default groups when the parent directory is removed, it does not automatically drop their reference counts. This responsibility lies with the driver.

By explicitly calling `configfs_remove_default_groups()` in the respective release functions, we ensure that the reference counts of the default groups are properly dropped. This correctly triggers the existing release callbacks (`f_midi2_ep_opts_release` and `f_midi2_block_opts_release`), which safely free the dynamically allocated memory in the correct order.

This approach is robust and idiomatic. It also safely handles dynamically created groups (e.g., `ep.1` created via `mkdir`), because their `default_groups` list is properly initialized and empty, making `configfs_remove_default_groups()` a safe no-op for them.

279/4 2026/07/30 14:41 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 7272
							output: 34
							thoughts: 143
						

Thoughts:
**Memory Leak in USB MIDI Gadget Driver**

Okay, so I've got a problem with a memory leak, specifically in `drivers/usb/gadget/function/f_midi2.c`. It looks like we're not properly cleaning up the configfs groups when they're released. The root cause appears to be the omission of `configfs_remove_default_groups()` calls in the release functions of those configfs groups.

The suggestion is pretty straightforward: add `configfs_remove_default_groups(&opts->func_inst.group);` to `f_midi2_free_inst()` and `configfs_remove_default_groups(to_config_group(item));` to `f_midi2_ep_opts_release()`. This should plug the leak. Time to dig into `drivers/usb/gadget/function/f_midi2.c` and confirm the proposed solution. Let's see if this aligns with my understanding of the configfs cleanup process.



280/4 2026/07/30 14:42 tool codesearch-file-index
0m Args:
map[SourceFile:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Entities:[map[Kind:function Name:append_config] map[Kind:function Name:append_configs] map[Kind:function Name:append_midi1_in_jack] map[Kind:function Name:append_midi1_out_jack] map[Kind:function Name:assign_block_descriptors] map[Kind:function Name:do_f_midi2_free] map[Kind:function Name:f_midi2_alloc] map[Kind:function Name:f_midi2_alloc_ep_reqs] map[Kind:function Name:f_midi2_alloc_inst] map[Kind:function Name:f_midi2_bind] map[Kind:function Name:f_midi2_block_opts_active_show] map[Kind:function Name:f_midi2_block_opts_active_store] map[Kind:function Name:f_midi2_block_opts_create] map[Kind:function Name:f_midi2_block_opts_direction_show] map[Kind:function Name:f_midi2_block_opts_direction_store] map[Kind:function Name:f_midi2_block_opts_first_group_show] map[Kind:function Name:f_midi2_block_opts_first_group_store] map[Kind:function Name:f_midi2_block_opts_is_midi1_show] map[Kind:function Name:f_midi2_block_opts_is_midi1_store] map[Kind:function Name:f_midi2_block_opts_midi1_first_group_show] map[Kind:function Name:f_midi2_block_opts_midi1_first_group_store] map[Kind:function Name:f_midi2_block_opts_midi1_num_groups_show] map[Kind:function Name:f_midi2_block_opts_midi1_num_groups_store] map[Kind:function Name:f_midi2_block_opts_midi_ci_version_show] map[Kind:function Name:f_midi2_block_opts_midi_ci_version_store] map[Kind:function Name:f_midi2_block_opts_name_show] map[Kind:function Name:f_midi2_block_opts_name_store] map[Kind:function Name:f_midi2_block_opts_num_groups_show] map[Kind:function Name:f_midi2_block_opts_num_groups_store] map[Kind:function Name:f_midi2_block_opts_release] map[Kind:function Name:f_midi2_block_opts_sysex8_streams_show] map[Kind:function Name:f_midi2_block_opts_sysex8_streams_store] map[Kind:function Name:f_midi2_block_opts_ui_hint_show] map[Kind:function Name:f_midi2_block_opts_ui_hint_store] map[Kind:function Name:f_midi2_create_card] map[Kind:function Name:f_midi2_create_usb_configs] map[Kind:function Name:f_midi2_disable] map[Kind:function Name:f_midi2_drop_reqs] map[Kind:function Name:f_midi2_ep_in_complete] map[Kind:function Name:f_midi2_ep_opts_create] map[Kind:function Name:f_midi2_ep_opts_ep_name_show] map[Kind:function Name:f_midi2_ep_opts_ep_name_store] map[Kind:function Name:f_midi2_ep_opts_family_show] map[Kind:function Name:f_midi2_ep_opts_family_store] map[Kind:function Name:f_midi2_ep_opts_manufacturer_show] map[Kind:function Name:f_midi2_ep_opts_manufacturer_store] map[Kind:function Name:f_midi2_ep_opts_model_show] map[Kind:function Name:f_midi2_ep_opts_model_store] map[Kind:function Name:f_midi2_ep_opts_product_id_show] map[Kind:function Name:f_midi2_ep_opts_product_id_store] map[Kind:function Name:f_midi2_ep_opts_protocol_caps_show] map[Kind:function Name:f_midi2_ep_opts_protocol_caps_store] map[Kind:function Name:f_midi2_ep_opts_protocol_show] map[Kind:function Name:f_midi2_ep_opts_protocol_store] map[Kind:function Name:f_midi2_ep_opts_release] map[Kind:function Name:f_midi2_ep_opts_sw_revision_show] map[Kind:function Name:f_midi2_ep_opts_sw_revision_store] map[Kind:function Name:f_midi2_ep_out_complete] map[Kind:function Name:f_midi2_free] map[Kind:function Name:f_midi2_free_card] map[Kind:function Name:f_midi2_free_ep] map[Kind:function Name:f_midi2_free_ep_reqs] map[Kind:function Name:f_midi2_free_inst] map[Kind:function Name:f_midi2_free_usb_configs] map[Kind:function Name:f_midi2_get_alt] map[Kind:function Name:f_midi2_init_ep] map[Kind:function Name:f_midi2_init_midi2_ep_in] map[Kind:function Name:f_midi2_init_midi2_ep_out] map[Kind:function Name:f_midi2_midi1_ep_in_complete] map[Kind:function Name:f_midi2_midi1_ep_out_complete] map[Kind:function Name:f_midi2_operation_mode_get] map[Kind:function Name:f_midi2_operation_mode_info] map[Kind:function Name:f_midi2_opts_block_drop] map[Kind:function Name:f_midi2_opts_block_make] map[Kind:function Name:f_midi2_opts_bool_store] map[Kind:function Name:f_midi2_opts_ep_drop] map[Kind:function Name:f_midi2_opts_ep_make] map[Kind:function Name:f_midi2_opts_iface_name_show] map[Kind:function Name:f_midi2_opts_iface_name_store] map[Kind:function Name:f_midi2_opts_process_ump_show] map[Kind:function Name:f_midi2_opts_process_ump_store] map[Kind:function Name:f_midi2_opts_release] map[Kind:function Name:f_midi2_opts_static_block_show] map[Kind:function Name:f_midi2_opts_static_block_store] map[Kind:function Name:f_midi2_opts_str_show] map[Kind:function Name:f_midi2_opts_str_store] map[Kind:function Name:f_midi2_opts_uint_show] map[Kind:function Name:f_midi2_opts_uint_store] map[Kind:function Name:f_midi2_queue_out_reqs] map[Kind:function Name:f_midi2_set_alt] map[Kind:function Name:f_midi2_setup] map[Kind:function Name:f_midi2_start_ep] map[Kind:function Name:f_midi2_start_eps] map[Kind:function Name:f_midi2_stop_eps] map[Kind:function Name:f_midi2_ump_close] map[Kind:function Name:f_midi2_ump_drain] map[Kind:function Name:f_midi2_ump_open] map[Kind:function Name:f_midi2_ump_trigger] map[Kind:function Name:f_midi2_unbind] map[Kind:function Name:fill_midi1_cable_mapping] map[Kind:function Name:fill_midi1_pending_buf] map[Kind:function Name:fill_midi2_class_desc] map[Kind:function Name:get_empty_request] map[Kind:function Name:make_name_string] map[Kind:function Name:midi2mod_exit] map[Kind:function Name:midi2mod_init] map[Kind:function Name:process_midi1_byte] map[Kind:function Name:process_midi1_pending_buf] map[Kind:function Name:process_midi1_transmit] map[Kind:function Name:process_ump] map[Kind:function Name:process_ump_stream_msg] map[Kind:function Name:process_ump_transmit] map[Kind:function Name:put_empty_request] map[Kind:function Name:queue_request_ep_in] map[Kind:function Name:queue_request_ep_raw] map[Kind:function Name:reply_ep_in] map[Kind:function Name:reply_ump_stream_ep_config] map[Kind:function Name:reply_ump_stream_ep_device] map[Kind:function Name:reply_ump_stream_ep_info] map[Kind:function Name:reply_ump_stream_ep_name] map[Kind:function Name:reply_ump_stream_ep_pid] map[Kind:function Name:reply_ump_stream_fb_info] map[Kind:function Name:reply_ump_stream_fb_name] map[Kind:function Name:reply_ump_stream_string] map[Kind:function Name:reverse_dir] map[Kind:function Name:to_f_midi2_block_opts] map[Kind:function Name:to_f_midi2_ep_opts] map[Kind:function Name:to_f_midi2_opts] map[Kind:function Name:ump_ep_name] map[Kind:function Name:ump_fb_name] map[Kind:function Name:ump_product_id] map[Kind:function Name:ump_to_usb_dir] map[Kind:function Name:verify_parameters] map[Kind:struct Name:f_midi2] map[Kind:struct Name:f_midi2_block] map[Kind:struct Name:f_midi2_ep] map[Kind:struct Name:f_midi2_midi1_port] map[Kind:struct Name:f_midi2_req_ctx] map[Kind:struct Name:f_midi2_usb_config] map[Kind:struct Name:f_midi2_usb_ep] map[Kind:struct Name:midi1_cable_mapping] map[Kind:struct Name:uac1_ac_header_descriptor_1] map[Kind:struct Name:usb_midi_out_jack_descriptor_1] map[Kind:struct Name:usb_ms20_endpoint_descriptor_32] map[Kind:struct Name:usb_ms_endpoint_descriptor_16] map[Kind:global_variable Name:__UNIQUE_ID_addressable_midi2mod_init_542] map[Kind:global_variable Name:__UNIQUE_ID_modinfo_540] map[Kind:global_variable Name:__UNIQUE_ID_modinfo_543] map[Kind:global_variable Name:__UNIQUE_ID_modinfo_544] map[Kind:global_variable Name:__UNIQUE_ID_modinfo_545] map[Kind:global_variable Name:__exitcall_midi2mod_exit] map[Kind:global_variable Name:f_midi2_attrs] map[Kind:global_variable Name:f_midi2_block_attrs] map[Kind:global_variable Name:f_midi2_block_item_ops] map[Kind:global_variable Name:f_midi2_block_opts_attr_active] map[Kind:global_variable Name:f_midi2_block_opts_attr_direction] map[Kind:global_variable Name:f_midi2_block_opts_attr_first_group] map[Kind:global_variable Name:f_midi2_block_opts_attr_is_midi1] map[Kind:global_variable Name:f_midi2_block_opts_attr_midi1_first_group] map[Kind:global_variable Name:f_midi2_block_opts_attr_midi1_num_groups] map[Kind:global_variable Name:f_midi2_block_opts_attr_midi_ci_version] map[Kind:global_variable Name:f_midi2_block_opts_attr_name] map[Kind:global_variable Name:f_midi2_block_opts_attr_num_groups] map[Kind:global_variable Name:f_midi2_block_opts_attr_sysex8_streams] map[Kind:global_variable Name:f_midi2_block_opts_attr_ui_hint] map[Kind:global_variable Name:f_midi2_block_type] map[Kind:global_variable Name:f_midi2_desc_mutex] map[Kind:global_variable Name:f_midi2_ep_attrs] map[Kind:global_variable Name:f_midi2_ep_group_ops] map[Kind:global_variable Name:f_midi2_ep_item_ops] map[Kind:global_variable Name:f_midi2_ep_opts_attr_ep_name] map[Kind:global_variable Name:f_midi2_ep_opts_attr_family] map[Kind:global_variable Name:f_midi2_ep_opts_attr_manufacturer] map[Kind:global_variable Name:f_midi2_ep_opts_attr_model] map[Kind:global_variable Name:f_midi2_ep_opts_attr_product_id] map[Kind:global_variable Name:f_midi2_ep_opts_attr_protocol] map[Kind:global_variable Name:f_midi2_ep_opts_attr_protocol_caps] map[Kind:global_variable Name:f_midi2_ep_opts_attr_sw_revision] map[Kind:global_variable Name:f_midi2_ep_type] map[Kind:global_variable Name:f_midi2_func_type] map[Kind:global_variable Name:f_midi2_group_ops] map[Kind:global_variable Name:f_midi2_item_ops] map[Kind:global_variable Name:f_midi2_opts_attr_iface_name] map[Kind:global_variable Name:f_midi2_opts_attr_process_ump] map[Kind:global_variable Name:f_midi2_opts_attr_static_block] map[Kind:global_variable Name:f_midi2_ump_ops] map[Kind:global_variable Name:gtb_desc] map[Kind:global_variable Name:gtb_header_desc] map[Kind:global_variable Name:midi2_audio_class_desc] map[Kind:global_variable Name:midi2_audio_descs] map[Kind:global_variable Name:midi2_audio_if_desc] map[Kind:global_variable Name:midi2_midi1_class_desc] map[Kind:global_variable Name:midi2_midi1_descs] map[Kind:global_variable Name:midi2_midi1_ep_in_class_desc] map[Kind:global_variable Name:midi2_midi1_ep_in_desc] map[Kind:global_variable Name:midi2_midi1_ep_in_descs] map[Kind:global_variable Name:midi2_midi1_ep_in_ss_comp_desc] map[Kind:global_variable Name:midi2_midi1_ep_in_ss_descs] map[Kind:global_variable Name:midi2_midi1_ep_out_class_desc] map[Kind:global_variable Name:midi2_midi1_ep_out_desc] map[Kind:global_variable Name:midi2_midi1_ep_out_descs] map[Kind:global_variable Name:midi2_midi1_ep_out_ss_comp_desc] map[Kind:global_variable Name:midi2_midi1_ep_out_ss_descs] map[Kind:global_variable Name:midi2_midi1_if_desc] map[Kind:global_variable Name:midi2_midi2_class_desc] map[Kind:global_variable Name:midi2_midi2_descs] map[Kind:global_variable Name:midi2_midi2_ep_in_ss_comp_desc] map[Kind:global_variable Name:midi2_midi2_ep_out_ss_comp_desc] map[Kind:global_variable Name:midi2_midi2_if_desc] map[Kind:global_variable Name:midi2usb_func] map[Kind:global_variable Name:operation_mode_ctl]]]

281/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 12277
							output: 47
							thoughts: 28
						

Thoughts:
Okay, here's my summary, presented as a stream of thought:

**Diving into MIDI-related Memory Management**

Alright, let's zero in on these two functions: `f_midi2_free_inst` and `f_midi2_ep_opts_release`. Immediately, the naming convention suggests these are intimately tied to memory management, particularly the release or freeing of resources related to MIDI 2.0 implementations. Given my expertise, I suspect `f_midi2_free_inst` likely handles the deallocation of an "instance," probably a structure or object representing a MIDI 2.0 instrument or endpoint. I'd anticipate it would involve recursive freeing of any dynamically allocated memory within that instance, ensuring no memory leaks. The emphasis on "free" strongly implies it's the counterpart to some prior "alloc" or "new" call.

`f_midi2_ep_opts_release`, on the other hand, the "ep_opts" leads me to believe this function is tied to the release of options or settings related to a MIDI 2.0 endpoint (EP). Perhaps we are talking about configuration parameters, capabilities, or other EP-specific metadata. It's likely involved with cleaning up data structures holding these options, maybe by freeing individual option elements, or a larger container holding them. It's a key function for preventing resource exhaustion when working with multiple MIDI devices or configurations.

Now I need to go deeper. What are the data structures these functions are meant to operate on? And most importantly, how do these functions interact with each other to guarantee that memory is managed safely and efficiently? I'm already formulating some questions in my head: What is the exact scope of these "instances" and "endpoint options"? Are there reference counting mechanisms or garbage collection strategies at play? What kind of error handling is implemented to manage potential issues during freeing or release operations? This is important. These two functions are the keys to a stable and robust implementation. Let's see if the code confirms my initial assessment.



282/4 2026/07/30 14:42 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_free_inst]

Results:
map[SourceCode:2636:	static void f_midi2_free_inst(struct usb_function_instance *f)
2637:	{
2638:		struct f_midi2_opts *opts;
2639:	
2640:		opts = container_of(f, struct f_midi2_opts, func_inst);
2641:	
2642:		kfree(opts->info.iface_name);
2643:		kfree(opts);
2644:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

283/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 12947
							output: 49
							thoughts: 13
						

Thoughts:
Okay, here's my interpretation of those thoughts, tailored for an expert audience, and delivered as a first-person summary:

**Digging into Release Optimization**

Alright, so I'm thinking about `f_midi2_ep_opts_release`. This function, I assume, is crucial for handling the release of something within a MIDI 2.0 endpoint options context. I'm immediately trying to unpack what precisely is being released. Is it resources? Memory allocated for some data structure? Handles to external devices or services? Or perhaps metadata? The "opts" part suggests there are several configurable options associated with this "release" operation. My mind is already running through potential scenarios: the graceful shutdown of a MIDI connection, deallocating buffer space after a transmission, closing a handle to a device that is no longer being used, and so on.

I need to understand the implications of this release. Are we talking about a simple deallocation, or a more involved process? Does this release function handle error conditions? Does it signal anything to other parts of the system? Are there potential race conditions I need to worry about if multiple threads are vying for the same resources? Does this release function need to free the structure and all its sub-elements in a well-defined way, or just the parent structure? I'm already envisioning potential problems with dangling pointers or memory leaks if this isn't handled meticulously. This release function could be critical. I must deeply understand its operation.



284/4 2026/07/30 14:42 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_ep_opts_release]

Results:
map[SourceCode:2472:	static void f_midi2_ep_opts_release(struct config_item *item)
2473:	{
2474:		struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
2475:	
2476:		kfree(opts->info.ep_name);
2477:		kfree(opts->info.product_id);
2478:		kfree(opts);
2479:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

285/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 13484
							output: 49
							thoughts: 83
						

Thoughts:
Here's my thought process, as if I were reviewing this code:

**Cleaning Up ConfigFS Resources in the MIDI Driver**

Okay, so I need to make some resource cleanup changes in the MIDI driver. Specifically, I'm thinking about how the `configfs` framework is managed, and I need to ensure that the default groups are properly removed to avoid any potential leaks or dangling pointers. I'm going to add `configfs_remove_default_groups(&opts->func_inst.group);` to the `f_midi2_free_inst` function. That seems straightforward enough to handle the instance's group.

Then, for the endpoint options, I need to add `configfs_remove_default_groups(to_config_group(item));` in the `f_midi2_ep_opts_release` function. This should take care of releasing the default group associated with those options. I need to make sure I am using the right group in each case, but this seems correct.

Now, before I commit these changes, it's a good practice to scan the rest of the file and confirm I haven't missed any other similar release functions where the `configfs` default groups need cleanup. I'll quickly look for other functions that handle resource release in the `f_midi2` driver file, just to be thorough. It's best to be systematic about this type of cleanup to prevent future problems.



286/4 2026/07/30 14:42 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_block_opts_release]

Results:
map[SourceCode:2310:	static void f_midi2_block_opts_release(struct config_item *item)
2311:	{
2312:		struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
2313:	
2314:		kfree(opts->info.name);
2315:		kfree(opts);
2316:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

287/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 14069
							output: 49
							thoughts: 38
						

Thoughts:
Okay, here's my interpretation of that thought process, assuming I'm deep in the weeds of MIDI 2.0 block option management:

**Digging into MIDI 2.0 Block Option Creation and Release**

Right, so `f_midi2_block_opts_release` doesn't seem to be setting any default groups. That’s a key observation. I need to understand why and how the groups are being handled, because that's fundamental to how the block options interact. It's likely that default groups are being set elsewhere, probably in the creation function or perhaps even in a related API call. Therefore, I need to understand how groups are being established in the block option structure, before the option block is being released. My next logical step is to dive right into the `f_midi2_block_opts_create` function. That's where I would expect to find the mechanism that sets up any initial state, including those crucial group assignments that `release` seemingly takes for granted. I'll need to confirm if it has default group configurations. Let's see what's happening in there.



288/4 2026/07/30 14:42 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_block_opts_create]

Results:
map[SourceCode:2328:	/* create a f_midi2_block_opts instance for the given block number */
2329:	static int f_midi2_block_opts_create(struct f_midi2_ep_opts *ep_opts,
2330:					     unsigned int blk,
2331:					     struct f_midi2_block_opts **block_p)
2332:	{
2333:		struct f_midi2_block_opts *block_opts;
2334:		int ret = 0;
2335:	
2336:		mutex_lock(&ep_opts->opts->lock);
2337:		if (ep_opts->opts->refcnt || ep_opts->blks[blk]) {
2338:			ret = -EBUSY;
2339:			goto out;
2340:		}
2341:	
2342:		block_opts = kzalloc_obj(*block_opts);
2343:		if (!block_opts) {
2344:			ret = -ENOMEM;
2345:			goto out;
2346:		}
2347:	
2348:		block_opts->ep = ep_opts;
2349:		block_opts->id = blk;
2350:	
2351:		/* set up the default values */
2352:		block_opts->info.direction = SNDRV_UMP_DIR_BIDIRECTION;
2353:		block_opts->info.first_group = 0;
2354:		block_opts->info.num_groups = 1;
2355:		block_opts->info.ui_hint = SNDRV_UMP_BLOCK_UI_HINT_BOTH;
2356:		block_opts->info.active = 1;
2357:	
2358:		ep_opts->blks[blk] = block_opts;
2359:		*block_p = block_opts;
2360:	
2361:	 out:
2362:		mutex_unlock(&ep_opts->opts->lock);
2363:		return ret;
2364:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

289/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 14999
							output: 49
							thoughts: 46
						

Thoughts:
**Digging into MIDI 2.0 Endpoint Option Initialization**

Okay, so I'm looking at `f_midi2_block_opts_create` here, and something's bugging me. It doesn't appear to be handling the default group setup for the `block_opts` structure. That's a bit unusual. I would have expected a routine like this to initialize *everything* related to its target. Let me just double check my assumption by quickly cross-referencing this routine's behavior with the structure's counterpart, `f_midi2_ep_opts_create`. This ought to clarify whether the design is intentionally distributed between two methods or if there’s a missing piece here. It is definitely worth looking into.



290/4 2026/07/30 14:42 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_ep_opts_create]

Results:
map[SourceCode:2497:	/* create a f_midi2_ep_opts instance */
2498:	static int f_midi2_ep_opts_create(struct f_midi2_opts *opts,
2499:					  unsigned int index,
2500:					  struct f_midi2_ep_opts **ep_p)
2501:	{
2502:		struct f_midi2_ep_opts *ep_opts;
2503:	
2504:		ep_opts = kzalloc_obj(*ep_opts);
2505:		if (!ep_opts)
2506:			return -ENOMEM;
2507:	
2508:		ep_opts->opts = opts;
2509:		ep_opts->index = index;
2510:	
2511:		/* set up the default values */
2512:		ep_opts->info.protocol = 2;
2513:		ep_opts->info.protocol_caps = 3;
2514:	
2515:		opts->eps[index] = ep_opts;
2516:		*ep_p = ep_opts;
2517:		return 0;
2518:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

291/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 15612
							output: 47
							thoughts: 21
						

Thoughts:
Here's my thought process, as requested:

**Debugging MIDI Group Allocation**

Okay, so I'm trying to figure out where these default MIDI groups are being added. My first instinct is to dive into the allocation code, specifically the `f_midi2_alloc_inst` function. It makes sense to start there, as that's where new instances are created. I'll need to carefully examine the logic within that function to trace the flow and identify the exact points where group membership is being assigned, especially the initial default groups. Hopefully, it's a straightforward conditional or loop, and I can quickly pinpoint the culprit! I'll be looking for clues like calls to group management functions or hardcoded assignments.



292/4 2026/07/30 14:42 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_alloc_inst]

Results:
map[SourceCode:2646:	/* gadget alloc_inst */
2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
2655:		if (!opts)
2656:			return ERR_PTR(-ENOMEM);
2657:	
2658:		mutex_init(&opts->lock);
2659:		opts->func_inst.free_func_inst = f_midi2_free_inst;
2660:		opts->info.process_ump = true;
2661:		opts->info.static_block = true;
2662:		opts->info.num_reqs = 32;
2663:		opts->info.req_buf_size = 512;
2664:	
2665:		/* create the default ep */
2666:		ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
2667:		if (ret) {
2668:			kfree(opts);
2669:			return ERR_PTR(ret);
2670:		}
2671:	
2672:		/* create the default block */
2673:		ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
2674:		if (ret) {
2675:			kfree(ep_opts);
2676:			kfree(opts);
2677:			return ERR_PTR(ret);
2678:		}
2679:	
2680:		/* set up the default MIDI1 (that is mandatory) */
2681:		block_opts->info.midi1_num_groups = 1;
2682:	
2683:		config_group_init_type_name(&opts->func_inst.group, "",
2684:					    &f_midi2_func_type);
2685:	
2686:		config_group_init_type_name(&ep_opts->group, "ep.0",
2687:					    &f_midi2_ep_type);
2688:		configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
2689:	
2690:		config_group_init_type_name(&block_opts->group, "block.0",
2691:					    &f_midi2_block_type);
2692:		configfs_add_default_group(&block_opts->group, &ep_opts->group);
2693:	
2694:		return &opts->func_inst;
2695:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

293/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 16666
							output: 26
							thoughts: 163
						

Thoughts:
**Analyzing ConfigFS Group Management in MIDI2 Driver**

Okay, so looking at this, I've tracked down the `configfs_add_default_group` function call within the `f_midi2_alloc_inst` function. Right, so `ep.0` is being added to `opts->func_inst.group`, and then `block.0` gets added to `ep_opts->group`. That makes sense. Now, the cleanup. When `f_midi2_free_inst` gets called, the driver should be calling `configfs_remove_default_groups(&opts->func_inst.group);`. Excellent. And on the endpoint option release with `f_midi2_ep_opts_release`, we need to call `configfs_remove_default_groups(to_config_group(item));`. This seems consistent so far. Just to be completely thorough though, I should double check to see if `configfs_add_default_group` is being used anywhere else in the code base. Gotta eliminate any potential leaks or unexpected behavior.



294/4 2026/07/30 14:42 tool codesearch-find-references
0m Args:
map[Name:configfs_add_default_group]

Results:
map[References:[map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:config_desc_make SourceFile:drivers/usb/gadget/configfs.c SourceLine:749] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:f_midi2_alloc_inst SourceFile:drivers/usb/gadget/function/f_midi2.c SourceLine:2688] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:f_midi2_alloc_inst SourceFile:drivers/usb/gadget/function/f_midi2.c SourceLine:2692] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:fsg_alloc_inst SourceFile:drivers/usb/gadget/function/f_mass_storage.c SourceLine:3531] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:gadgets_make SourceFile:drivers/usb/gadget/configfs.c SourceLine:2002] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:gadgets_make SourceFile:drivers/usb/gadget/configfs.c SourceLine:2006] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:gadgets_make SourceFile:drivers/usb/gadget/configfs.c SourceLine:2010] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:gadgets_make SourceFile:drivers/usb/gadget/configfs.c SourceLine:2014] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:gadgets_make SourceFile:drivers/usb/gadget/configfs.c SourceLine:2018] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_cluster SourceFile:fs/dlm/config.c SourceLine:443] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_cluster SourceFile:fs/dlm/config.c SourceLine:444] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_cma_dev SourceFile:drivers/infiniband/core/cma_configfs.c SourceLine:305] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_cma_ports SourceFile:drivers/infiniband/core/cma_configfs.c SourceLine:227] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_connector_group SourceFile:drivers/gpu/drm/vkms/vkms_configfs.c SourceLine:673] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_device_group SourceFile:drivers/gpu/drm/vkms/vkms_configfs.c SourceLine:788] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_device_group SourceFile:drivers/gpu/drm/vkms/vkms_configfs.c SourceLine:792] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_device_group SourceFile:drivers/gpu/drm/vkms/vkms_configfs.c SourceLine:796] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_device_group SourceFile:drivers/gpu/drm/vkms/vkms_configfs.c SourceLine:800] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_encoder_group SourceFile:drivers/gpu/drm/vkms/vkms_configfs.c SourceLine:506] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_plane_group SourceFile:drivers/gpu/drm/vkms/vkms_configfs.c SourceLine:389] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:make_space SourceFile:fs/dlm/config.c SourceLine:492] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nullb_add_fault_config SourceFile:drivers/block/null_blk/main.c SourceLine:663] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nullb_add_fault_config SourceFile:drivers/block/null_blk/main.c SourceLine:664] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nullb_add_fault_config SourceFile:drivers/block/null_blk/main.c SourceLine:665] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_init_configfs SourceFile:drivers/nvme/target/configfs.c SourceLine:2372] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_init_configfs SourceFile:drivers/nvme/target/configfs.c SourceLine:2377] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_init_configfs SourceFile:drivers/nvme/target/configfs.c SourceLine:2382] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_ports_make SourceFile:drivers/nvme/target/configfs.c SourceLine:2085] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_ports_make SourceFile:drivers/nvme/target/configfs.c SourceLine:2089] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_ports_make SourceFile:drivers/nvme/target/configfs.c SourceLine:2093] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_ports_make SourceFile:drivers/nvme/target/configfs.c SourceLine:2100] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_subsys_make SourceFile:drivers/nvme/target/configfs.c SourceLine:1757] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:nvmet_subsys_make SourceFile:drivers/nvme/target/configfs.c SourceLine:1761] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:o2nm_cluster_group_make_group SourceFile:fs/ocfs2/cluster/nodemanager.c SourceLine:706] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:o2nm_cluster_group_make_group SourceFile:fs/ocfs2/cluster/nodemanager.c SourceLine:710] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_init_configfs SourceFile:drivers/target/target_core_configfs.c SourceLine:3766] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_init_configfs SourceFile:drivers/target/target_core_configfs.c SourceLine:3772] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_init_configfs SourceFile:drivers/target/target_core_configfs.c SourceLine:3780] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_init_configfs SourceFile:drivers/target/target_core_configfs.c SourceLine:3793] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_make_subdev SourceFile:drivers/target/target_core_configfs.c SourceLine:3445] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_make_subdev SourceFile:drivers/target/target_core_configfs.c SourceLine:3449] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_make_subdev SourceFile:drivers/target/target_core_configfs.c SourceLine:3453] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_make_subdev SourceFile:drivers/target/target_core_configfs.c SourceLine:3457] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_make_subdev SourceFile:drivers/target/target_core_configfs.c SourceLine:3462] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_make_subdev SourceFile:drivers/target/target_core_configfs.c SourceLine:3467] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_make_subdev SourceFile:drivers/target/target_core_configfs.c SourceLine:3480] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_core_register_fabric SourceFile:drivers/target/target_core_configfs.c SourceLine:257] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_lun SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:769] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_mappedlun SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:313] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_nodeacl SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:391] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_nodeacl SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:396] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_nodeacl SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:401] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_nodeacl SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:406] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_tpg SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:948] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_tpg SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:953] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_tpg SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:958] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_tpg SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:963] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_tpg SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:968] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_tpg SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:973] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_wwn SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:1149] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_fabric_make_wwn SourceFile:drivers/target/target_core_fabric_configfs.c SourceLine:1153] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_stat_setup_dev_default_groups SourceFile:drivers/target/target_core_stat.c SourceLine:400] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_stat_setup_dev_default_groups SourceFile:drivers/target/target_core_stat.c SourceLine:405] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_stat_setup_dev_default_groups SourceFile:drivers/target/target_core_stat.c SourceLine:410] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_stat_setup_mappedlun_default_groups SourceFile:drivers/target/target_core_stat.c SourceLine:1305] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_stat_setup_mappedlun_default_groups SourceFile:drivers/target/target_core_stat.c SourceLine:1310] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_stat_setup_port_default_groups SourceFile:drivers/target/target_core_stat.c SourceLine:807] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_stat_setup_port_default_groups SourceFile:drivers/target/target_core_stat.c SourceLine:812] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:target_stat_setup_port_default_groups SourceFile:drivers/target/target_core_stat.c SourceLine:817] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:usb_os_desc_prepare_interf_dir SourceFile:drivers/usb/gadget/configfs.c SourceLine:1550] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:usb_os_desc_prepare_interf_dir SourceFile:drivers/usb/gadget/configfs.c SourceLine:1564] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:uvcg_color_matching_create_children SourceFile:drivers/usb/gadget/function/uvc_configfs.c SourceLine:3113] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:uvcg_config_create_group SourceFile:drivers/usb/gadget/function/uvc_configfs.c SourceLine:166] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:uvcg_control_class_create_children SourceFile:drivers/usb/gadget/function/uvc_configfs.c SourceLine:1448] map[ReferenceKind:calls ReferencingEntityKind:function ReferencingEntityName:uvcg_streaming_class_create_children SourceFile:drivers/usb/gadget/function/uvc_configfs.c SourceLine:3564]] TruncatedOutput:false]

295/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 21435
							output: 49
							thoughts: 73
						

Thoughts:
**Examining the MIDI2 Driver's Configuration**

Okay, so I'm looking into the `f_midi2.c` file and specifically focusing on calls to `configfs_add_default_group`. My primary interest here is how the default configuration group for MIDI2 is being handled. I recall that `configfs_add_default_group` only appears to be called within `f_midi2_alloc_inst`. This seems straightforward, but I want to be thorough. I need to make sure I haven't missed something.

Now, I'm going to shift my focus and examine `f_midi2_opts_ep_make` and `f_midi2_opts_block_make`. I'll need to double check how these functions interact with the configfs setup, just in case there's any implicit or indirect handling of the default group that I missed. I want a complete picture.



296/4 2026/07/30 14:42 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_opts_ep_make]

Results:
map[SourceCode:2520:	/* make_group callback for an EP */
2521:	static struct config_group *
2522:	f_midi2_opts_ep_make(struct config_group *group, const char *name)
2523:	{
2524:		struct f_midi2_opts *opts;
2525:		struct f_midi2_ep_opts *ep_opts;
2526:		unsigned int index;
2527:		int ret;
2528:	
2529:		if (strncmp(name, "ep.", 3))
2530:			return ERR_PTR(-EINVAL);
2531:		ret = kstrtouint(name + 3, 10, &index);
2532:		if (ret)
2533:			return ERR_PTR(ret);
2534:	
2535:		opts = to_f_midi2_opts(&group->cg_item);
2536:		if (index >= MAX_UMP_EPS)
2537:			return ERR_PTR(-EINVAL);
2538:		if (opts->eps[index])
2539:			return ERR_PTR(-EBUSY);
2540:		ret = f_midi2_ep_opts_create(opts, index, &ep_opts);
2541:		if (ret)
2542:			return ERR_PTR(ret);
2543:	
2544:		config_group_init_type_name(&ep_opts->group, name, &f_midi2_ep_type);
2545:		return &ep_opts->group;
2546:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

297/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 22223
							output: 49
							thoughts: 182
						

Thoughts:
**Analyzing MIDI Endpoint Creation in the Configuration Filesystem**

Okay, so `f_midi2_opts_ep_make` is responsible for creating a new endpoint group, which is good. But it seems like it *doesn't* automatically attach any default groups to this new endpoint, and that's the part that's sparking questions. I'm recalling that `f_midi2_alloc_inst` *does* add `block.0` to `ep.0` as a default. That's the established pattern.

Now, here's where my concern lies: if a user creates an endpoint directory directly, using `mkdir` say to make `ep.1`, is the `block.0` group automatically included? It's crucial for the default functionality we're expecting.

A quick review of the code tells me `f_midi2_opts_ep_make` doesn't call `configfs_add_default_group`. So, if the endpoint is created without the main function, it seems very likely that `ep.1` created via `mkdir` won't have `block.0` by default. And that's not the behavior we want.

I need to confirm this. I think the next logical step would be to review `f_midi2_opts_block_make` just to be sure.



298/4 2026/07/30 14:42 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_opts_block_make]

Results:
map[SourceCode:2366:	/* make_group callback for a block */
2367:	static struct config_group *
2368:	f_midi2_opts_block_make(struct config_group *group, const char *name)
2369:	{
2370:		struct f_midi2_ep_opts *ep_opts;
2371:		struct f_midi2_block_opts *block_opts;
2372:		unsigned int blk;
2373:		int ret;
2374:	
2375:		if (strncmp(name, "block.", 6))
2376:			return ERR_PTR(-EINVAL);
2377:		ret = kstrtouint(name + 6, 10, &blk);
2378:		if (ret)
2379:			return ERR_PTR(ret);
2380:	
2381:		ep_opts = to_f_midi2_ep_opts(&group->cg_item);
2382:	
2383:		if (blk >= SNDRV_UMP_MAX_BLOCKS)
2384:			return ERR_PTR(-EINVAL);
2385:		if (ep_opts->blks[blk])
2386:			return ERR_PTR(-EBUSY);
2387:		ret = f_midi2_block_opts_create(ep_opts, blk, &block_opts);
2388:		if (ret)
2389:			return ERR_PTR(ret);
2390:	
2391:		config_group_init_type_name(&block_opts->group, name,
2392:					    &f_midi2_block_type);
2393:		return &block_opts->group;
2394:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

299/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 23246
							output: 219
							thoughts: 74
						

Thoughts:
Okay, let's break this down.

**Addressing Default Group Management in MIDI 2.0 Instance Allocation and Release**

Right, so I've pinpointed the crux of the issue. The function `f_midi2_alloc_inst` is the *sole* responsible party for adding default groups to the MIDI 2.0 instance. Consequently, `f_midi2_free_inst` and `f_midi2_ep_opts_release` absolutely *must* handle their removal during the deallocation process. That’s the key here – ensuring these defaults are properly cleaned up.

Therefore, the logical next step is to get in there and edit `f_midi2_free_inst` and `f_midi2_ep_opts_release`. It's pretty straightforward: I need to add the code to remove these defaults during the appropriate stages of those functions. This feels like a quick and surgical change.



300/4 2026/07/30 14:42 tool codeeditor
0m Args:
map[CurrentCode:static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	kfree(opts->info.iface_name);
	kfree(opts);
} NewCode:static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group);
	kfree(opts->info.iface_name);
	kfree(opts);
} SourceFile:drivers/usb/gadget/function/f_midi2.c]

Results:
map[]

301/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 23743
							output: 229
							thoughts: 14
						

Thoughts:
Okay, here's my summary, taking on the persona you've described:

**Analyzing `f_midi2_ep_opts_release`**

Alright, let's dive into this `f_midi2_ep_opts_release` function. My initial thought is to assess its role within the larger context of the MIDI 2.0 endpoint protocol. It's a "release" function, so I'm immediately thinking memory management, resource cleanup, and potentially de-allocation. Given my experience, I'm expecting this to be crucial for ensuring endpoint stability and preventing memory leaks or dangling pointers. I'll need to scrutinize how it handles different data structures associated with the endpoint options. Is it freeing individual option structures? Are there nested allocations that need to be recursively released? What about potential synchronization concerns? Are there any mutexes or other concurrency primitives involved to protect shared resources during the release process? I need to look for any potential for double-frees or use-after-free vulnerabilities. Beyond the simple mechanics of deallocation, I'm going to consider any side effects or dependencies it might have on the endpoint state. Does calling this function put the endpoint in a specific state? Are there any important state transitions that need to be accounted for? Overall, a robust implementation of this function is vital for the integrity of the endpoint.



302/4 2026/07/30 14:42 tool codeeditor
0m Args:
map[CurrentCode:static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
} NewCode:static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item));
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
} SourceFile:drivers/usb/gadget/function/f_midi2.c]

Results:
map[]

303/4 2026/07/30 14:42 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 24273
							output: 30
							thoughts: 7
						

Thoughts:
Okay, I'm ready to dive into that "diff" and give you my expert take. Here's my thought process:

**Diving into the Code Change**

Alright, a diff is in front of me, which means we're looking at a comparison between two versions of some code, config, or data. My first instinct is to zoom in on the most crucial areas of the changes – those likely to have the biggest impact, or where I expect potential problems. I immediately start scanning for:

*   **Core Logic Alterations:** What fundamental algorithms or data structures have been modified? That's always my primary focus.
*   **Dependency Updates:** Any changes to external libraries or APIs? Those can introduce breaking changes or security vulnerabilities if not carefully vetted.
*   **Performance Implications:** Is the change likely to speed things up, slow things down, or introduce any new bottlenecks? I'm looking for anything that could impact throughput or latency.
*   **Security Concerns:** Did the change touch any areas related to authentication, authorization, or data handling? Any red flags there are going to get my immediate attention.
*   **Error Handling:** Are there any new error conditions, and how are they being handled? Proper error management is critical, and often an afterthought that can be improved.
*   **Edge Cases:** I'm mentally testing the changes against scenarios. Any potential edge cases I can see? The diff is likely to show what the developer tested, so I can use that to formulate my own tests.
*   **Stylistic Changes:** Does the code follow our style guide? Consistency is crucial for maintainability.

Now, as I go through the diff, I'm already formulating test cases, potential follow-up questions, and likely refactor suggestions in my head. I'm going to look for any area that is not quite consistent with the standard or the project's standards. My review is going to address what the code does, and what it *should* do, as well as considering if the change is a complete solution.



304/4 2026/07/30 14:43 tool patch-diff
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2466,20 +2466,21 @@ static struct configfs_attribute *f_midi2_ep_attrs[] = {
 	&f_midi2_ep_opts_attr_family,
 	&f_midi2_ep_opts_attr_model,
 	&f_midi2_ep_opts_attr_sw_revision,
 	NULL,
 };
 
 static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
 }
 
 static const struct configfs_item_operations f_midi2_ep_item_ops = {
 	.release	= f_midi2_ep_opts_release,
 };
 
 static const struct configfs_group_operations f_midi2_ep_group_ops = {
@@ -2632,20 +2633,21 @@ static const struct config_item_type f_midi2_func_type = {
 	.ct_attrs	= f_midi2_attrs,
 	.ct_owner	= THIS_MODULE,
 };
 
 static void f_midi2_free_inst(struct usb_function_instance *f)
 {
 	struct f_midi2_opts *opts;
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 
 /* gadget alloc_inst */
 static struct usb_function_instance *f_midi2_alloc_inst(void)
 {
 	struct f_midi2_opts *opts;
 	struct f_midi2_ep_opts *ep_opts;
 	struct f_midi2_block_opts *block_opts;
]

305/4 2026/07/30 14:43 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 25386
							output: 47
							thoughts: 546
						

Thoughts:
**My Analysis of the MIDI Function Instance Removal**

Okay, the diff looks good at first glance. But I need to be absolutely certain this memory management is correct, especially with ConfigFS. Let's trace the calls, starting with the removal of default groups using `configfs_remove_default_groups(&opts->func_inst.group)`.

Right, `configfs_remove_default_groups` iterates through the `default_groups` and calls `config_item_put` on each. Good, standard practice. Now, when `config_item_put` decrements the reference count to zero, the item's `release` function is called, which is defined in `ci_type->ct_item_ops->release(item)`.

For the `ep.0` item, the `ci_type` is `f_midi2_ep_type`, and the associated operations, `ct_item_ops`, are defined by `f_midi2_ep_item_ops`. And, as I recall, `.release` within that structure is `f_midi2_ep_opts_release`. So, yes, `f_midi2_ep_opts_release` *will* be called.

Now, inside `f_midi2_ep_opts_release`, we have *another* call to `configfs_remove_default_groups`, this time operating on the `to_config_group(item)` – which would be `ep.0` from above. This will iterate over `ep.0`'s `default_groups`, which is just `block.0`. So, `config_item_put` gets called on `block.0`.

For `block.0`, the `ci_type` is `f_midi2_block_type`, and `ct_item_ops` is `f_midi2_block_item_ops`. This has `.release = f_midi2_block_opts_release`. Therefore, `f_midi2_block_opts_release` gets called, and as I recall from its implementation, it frees `block_opts`, which is the correct behaviour. Seems solid, but let's be thorough.

Hold on a minute. What about other default groups within `opts->func_inst.group`? I need to rule out any unexpected behaviour. No, upon double-checking, only `ep.0` is added to `opts->func_inst.group` as a default group. And within `ep.0`, only `block.0` is added as a default group. So, that's clean.

Alright, let's look for other places `configfs_remove_default_groups` is called or *should* be called to confirm a clean state overall. It's called in `f_midi2_free_inst`, as expected, and also within `f_midi2_ep_opts_release`, which we've already traced.

One last thing, let me just quickly scan `f_midi2_alloc_inst` again. I want to make sure no other function instances are setting default groups that are not handled as intended. *I will check for the usage of default groups.*



306/4 2026/07/30 14:43 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_alloc_inst]

Results:
map[SourceCode:2646:	/* gadget alloc_inst */
2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
2655:		if (!opts)
2656:			return ERR_PTR(-ENOMEM);
2657:	
2658:		mutex_init(&opts->lock);
2659:		opts->func_inst.free_func_inst = f_midi2_free_inst;
2660:		opts->info.process_ump = true;
2661:		opts->info.static_block = true;
2662:		opts->info.num_reqs = 32;
2663:		opts->info.req_buf_size = 512;
2664:	
2665:		/* create the default ep */
2666:		ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
2667:		if (ret) {
2668:			kfree(opts);
2669:			return ERR_PTR(ret);
2670:		}
2671:	
2672:		/* create the default block */
2673:		ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
2674:		if (ret) {
2675:			kfree(ep_opts);
2676:			kfree(opts);
2677:			return ERR_PTR(ret);
2678:		}
2679:	
2680:		/* set up the default MIDI1 (that is mandatory) */
2681:		block_opts->info.midi1_num_groups = 1;
2682:	
2683:		config_group_init_type_name(&opts->func_inst.group, "",
2684:					    &f_midi2_func_type);
2685:	
2686:		config_group_init_type_name(&ep_opts->group, "ep.0",
2687:					    &f_midi2_ep_type);
2688:		configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
2689:	
2690:		config_group_init_type_name(&block_opts->group, "block.0",
2691:					    &f_midi2_block_type);
2692:		configfs_add_default_group(&block_opts->group, &ep_opts->group);
2693:	
2694:		return &opts->func_inst;
2695:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

307/4 2026/07/30 14:43 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 27501
							output: 49
							thoughts: 974
						

Thoughts:
**Analyzing Memory Management in MIDI2 USB Gadget Driver**

Okay, let's break down this memory management logic. Initially, I was concerned about potential double frees or use-after-free scenarios in the MIDI2 gadget driver.

First, I looked at the creation process.  `f_midi2_ep_opts_create` can fail, in which case it returns an error and frees `opts`.  `f_midi2_block_opts_create` can also fail, in which case it frees both `ep_opts` and `opts`.  I noticed that `f_midi2_ep_opts_create` allocates `ep_opts` and assigns it to `opts->eps[0]`. If `f_midi2_block_opts_create` fails, it frees `ep_opts`, but `opts->eps[0]` still pointed to the freed memory. However, `opts` is immediately freed afterward, so that potential dangling pointer doesn't matter in the failure case. That's good.

Looking at the code for these functions, I can see that `f_midi2_ep_opts_create` initializes `ep_opts`, assigning it to `opts->eps[index]` and also to `*ep_p`.  This is followed by the `f_midi2_block_opts_create` that can fail, and then freeing both `ep_opts` and `opts` in that failure case. Everything checks out here.

Next, I considered a successful allocation followed by a deallocation sequence.  If `f_midi2_alloc_inst` succeeds, and later `f_midi2_free_inst` is called, `f_midi2_free_inst` calls `configfs_remove_default_groups` on `opts->func_inst.group`.  This triggers a chain of events:  the refcount of `ep.0` drops, calling `f_midi2_ep_opts_release`, which then calls `configfs_remove_default_groups` on `to_config_group(item)` (i.e., `block.0`), which in turn calls `f_midi2_block_opts_release`. The `f_midi2_block_opts_release` frees `block_opts`, and then `f_midi2_ep_opts_release` frees `ep_opts`. Finally, `f_midi2_free_inst` frees `opts`. I was worried that `opts->eps[0]` would still point to a freed `ep_opts`, and `ep_opts->blks[0]` would still point to a freed `block_opts`. After reviewing the code and the order of operations, however, `opts` is freed last. Since `opts` is freed at the end of the deallocation, all the associated memory within `opts`, including the `opts->eps` array, becomes invalid. It's safe since `opts` is no longer used.

I was also thinking about dynamically created EPs and blocks. If a user creates a new endpoint `ep.1` via `mkdir`, `f_midi2_opts_ep_make` is invoked, which calls `f_midi2_ep_opts_create`.  Then, when the user removes `ep.1` via `rmdir`, `f_midi2_opts_ep_drop` would be called.  This should all be handled by configfs.

Therefore, the memory management appears sound, as long as `opts` is freed at the end. All memory is correctly freed in all cases.



308/4 2026/07/30 14:43 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_opts_ep_drop]

Results:
map[SourceCode:2548:	/* drop_item callback for an EP */
2549:	static void
2550:	f_midi2_opts_ep_drop(struct config_group *group, struct config_item *item)
2551:	{
2552:		struct f_midi2_ep_opts *ep_opts = to_f_midi2_ep_opts(item);
2553:	
2554:		mutex_lock(&ep_opts->opts->lock);
2555:		ep_opts->opts->eps[ep_opts->index] = NULL;
2556:		mutex_unlock(&ep_opts->opts->lock);
2557:		config_item_put(item);
2558:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

309/4 2026/07/30 14:43 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 29520
							output: 37
							thoughts: 460
						

Thoughts:
**Analyzing the Lifecycle of Default ConfigFS Groups**

Okay, so I'm looking at how we handle the destruction of MIDI device configurations within ConfigFS, specifically focusing on these default groups. It looks like `f_midi2_opts_ep_drop` is used to remove an endpoint, setting `ep_opts->opts->eps[ep_opts->index] = NULL;` and then calling `config_item_put(item)`. But here's the crucial point: this function *isn't* used for the default endpoint, `ep.0`. Since `ep.0` isn't created via `mkdir`, its lifecycle is different.

When `f_midi2_free_inst` is called, it triggers `configfs_remove_default_groups`, which calls `config_item_put` on `ep.0`. This means the call goes straight to `f_midi2_ep_opts_release`. Critically, `opts->eps[0]` isn't explicitly set to NULL in this path. However, because the entire `opts` structure is being freed, it becomes a moot point.

Next, I'm thinking about `block.0`, which is a default group belonging to `ep.0`. When `f_midi2_ep_opts_release` also calls `configfs_remove_default_groups`, it calls `config_item_put` on `block.0`. This call ends up in `f_midi2_block_opts_release`. Here too, `ep_opts->blks[0]` isn't set to NULL. Just like the `ep.0` case, `ep_opts` is being freed.

Now, the important question is: what happens if a user attempts to remove these default groups, using `rmdir`? The initial thought is that `rmdir` on `block.0` *should* be blocked, given its default nature. Wait, is it? Isn't there something about how ConfigFS handles default groups? My gut says no, ConfigFS should not allow `rmdir` on default groups, but I need to make sure. I thought maybe ConfigFS does in some cases? No, no, it should return an error, either `-ENOENT` or `-EPERM`. I need to verify how `configfs_rmdir` behaves. I need to refresh myself on how this whole thing works.



310/4 2026/07/30 14:43 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_rmdir]

Results:
map[SourceCode:1469:	static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1470:	{
1471:		struct config_item *parent_item;
1472:		struct config_item *item;
1473:		struct configfs_subsystem *subsys;
1474:		struct configfs_dirent *sd;
1475:		struct configfs_fragment *frag;
1476:		struct module *subsys_owner = NULL, *dead_item_owner = NULL;
1477:		int ret;
1478:	
1479:		sd = dentry->d_fsdata;
1480:		if (sd->s_type & CONFIGFS_USET_DEFAULT)
1481:			return -EPERM;
1482:	
1483:		/* Get a working ref until we have the child */
1484:		parent_item = configfs_get_config_item(dentry->d_parent);
1485:		subsys = to_config_group(parent_item)->cg_subsys;
1486:		BUG_ON(!subsys);
1487:	
1488:		if (!parent_item->ci_type) {
1489:			config_item_put(parent_item);
1490:			return -EINVAL;
1491:		}
1492:	
1493:		/* configfs_mkdir() shouldn't have allowed this */
1494:		BUG_ON(!subsys->su_group.cg_item.ci_type);
1495:		subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
1496:	
1497:		/*
1498:		 * Ensure that no racing symlink() will make detach_prep() fail while
1499:		 * the new link is temporarily attached
1500:		 */
1501:		do {
1502:			struct dentry *wait;
1503:	
1504:			mutex_lock(&configfs_symlink_mutex);
1505:			spin_lock(&configfs_dirent_lock);
1506:			/*
1507:			 * Here's where we check for dependents.  We're protected by
1508:			 * configfs_dirent_lock.
1509:			 * If no dependent, atomically tag the item as dropping.
1510:			 */
1511:			ret = sd->s_dependent_count ? -EBUSY : 0;
1512:			if (!ret) {
1513:				ret = configfs_detach_prep(sd, &wait);
1514:				if (ret)
1515:					configfs_detach_rollback(sd);
1516:			}
1517:			spin_unlock(&configfs_dirent_lock);
1518:			mutex_unlock(&configfs_symlink_mutex);
1519:	
1520:			if (ret) {
1521:				if (ret != -EAGAIN) {
1522:					config_item_put(parent_item);
1523:					return ret;
1524:				}
1525:	
1526:				/* Wait until the racing operation terminates */
1527:				inode_lock(d_inode(wait));
1528:				inode_unlock(d_inode(wait));
1529:				dput(wait);
1530:			}
1531:		} while (ret == -EAGAIN);
1532:	
1533:		frag = sd->s_frag;
1534:		if (down_write_killable(&frag->frag_sem)) {
1535:			spin_lock(&configfs_dirent_lock);
1536:			configfs_detach_rollback(sd);
1537:			spin_unlock(&configfs_dirent_lock);
1538:			config_item_put(parent_item);
1539:			return -EINTR;
1540:		}
1541:		frag->frag_dead = true;
1542:		up_write(&frag->frag_sem);
1543:	
1544:		/* Get a working ref for the duration of this function */
1545:		item = configfs_get_config_item(dentry);
1546:	
1547:		/* Drop reference from above, item already holds one. */
1548:		config_item_put(parent_item);
1549:	
1550:		if (item->ci_type)
1551:			dead_item_owner = item->ci_type->ct_owner;
1552:	
1553:		if (sd->s_type & CONFIGFS_USET_DIR) {
1554:			configfs_detach_group(dentry);
1555:	
1556:			mutex_lock(&subsys->su_mutex);
1557:			client_disconnect_notify(parent_item, item);
1558:			unlink_group(to_config_group(item));
1559:		} else {
1560:			configfs_detach_item(dentry);
1561:	
1562:			mutex_lock(&subsys->su_mutex);
1563:			client_disconnect_notify(parent_item, item);
1564:			unlink_obj(item);
1565:		}
1566:	
1567:		client_drop_item(parent_item, item);
1568:		mutex_unlock(&subsys->su_mutex);
1569:	
1570:		/* Drop our reference from above */
1571:		config_item_put(item);
1572:	
1573:		module_put(dead_item_owner);
1574:		module_put(subsys_owner);
1575:	
1576:		return 0;
1577:	}
 SourceFile:fs/configfs/dir.c]

311/4 2026/07/30 14:43 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 32156
							output: 38
							thoughts: 184
						

Thoughts:
**Analyzing the `rmdir` Behavior in ConfigFS**

Okay, so I see that if a "default" group is set, the system will return `-EPERM` if someone tries to `rmdir` it. That makes sense; we wouldn't want those getting deleted accidentally.

But, a new thought is popping up: What happens if the user attempts to `rmdir` the *function instance* itself? That's a directory created using `mkdir` within configfs, right? I'm picturing the process. If someone runs `rmdir` on the instance, `configfs_rmdir` will be called. Then `configfs_rmdir` calls `configfs_detach_group`, which is supposed to remove the dentries of the default groups. Then `client_drop_item` is called, which calls `f_midi2_func_type`'s `drop_item`.

Okay, I need to trace this... Wait, that function instance directory is created by `function_make` in `drivers/usb/gadget/configfs.c`. Yes! Let's go check what is in `function_make` now.



312/4 2026/07/30 14:43 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/configfs.c Name:function_make]

Results:
map[SourceCode: 601:	static struct config_group *function_make(
 602:			struct config_group *group,
 603:			const char *name)
 604:	{
 605:		struct gadget_info *gi;
 606:		struct usb_function_instance *fi;
 607:		char buf[MAX_NAME_LEN];
 608:		char *func_name;
 609:		char *instance_name;
 610:		int ret;
 611:	
 612:		if (strlen(name) >= MAX_NAME_LEN)
 613:			return ERR_PTR(-ENAMETOOLONG);
 614:	
 615:		scnprintf(buf, MAX_NAME_LEN, "%s", name);
 616:	
 617:		func_name = buf;
 618:		instance_name = strchr(func_name, '.');
 619:		if (!instance_name) {
 620:			pr_err("Unable to locate . in FUNC.INSTANCE\n");
 621:			return ERR_PTR(-EINVAL);
 622:		}
 623:		*instance_name = '\0';
 624:		instance_name++;
 625:	
 626:		fi = usb_get_function_instance(func_name);
 627:		if (IS_ERR(fi))
 628:			return ERR_CAST(fi);
 629:	
 630:		ret = config_item_set_name(&fi->group.cg_item, "%s", name);
 631:		if (ret) {
 632:			usb_put_function_instance(fi);
 633:			return ERR_PTR(ret);
 634:		}
 635:		if (fi->set_inst_name) {
 636:			ret = fi->set_inst_name(fi, instance_name);
 637:			if (ret) {
 638:				usb_put_function_instance(fi);
 639:				return ERR_PTR(ret);
 640:			}
 641:		}
 642:	
 643:		gi = container_of(group, struct gadget_info, functions_group);
 644:	
 645:		mutex_lock(&gi->lock);
 646:		list_add_tail(&fi->cfs_list, &gi->available_func);
 647:		mutex_unlock(&gi->lock);
 648:		return &fi->group;
 649:	}
 SourceFile:drivers/usb/gadget/configfs.c]

313/4 2026/07/30 14:43 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 33356
							output: 38
							thoughts: 20
						

Thoughts:
Okay, here's my interpretation of that thought process, assuming I'm an expert in this field, and speaking from the first-person perspective:

**Garbage Collection and Function Instance Destruction**

Alright, so the core of what's happening here is pretty straightforward, but the nuances are important. My thought process is triggered by a call to `rmdir` on a function instance. Instantly, I recognize that this signifies the process of removing a directory entry that represents this function instance. Behind the scenes, the operating system or runtime is managing the instance's lifecycle and, critically, its eventual destruction. So, the key is what happens when that directory entry gets nuked.

The fact that `function_drop` is specifically called when `rmdir` is invoked is telling. It immediately flags to me that we're dealing with a sophisticated memory management or resource-handling scheme. `function_drop` isn't just a generic cleanup function; it's intricately linked to the destruction trigger – the *removal* of the symbolic representation of the function instance in the file system. It suggests that there are potentially custom cleanup procedures for the memory that the instance lives in, which could have been managed directly or implicitly, or possibly allocated in a place that is not easily auto-cleaned. This is very important.

My assumption is that `function_drop` is *the* place where all necessary resources associated with that specific function instance are explicitly released. This could include things like closing any file handles the function might have been using, deallocating any dynamically allocated memory specific to this instance, or releasing any other operating system resources it holds. The call to `rmdir` acts as the trigger to initiate these cleanup steps. It's a clean, deterministic way to signal the end of the instance's life and ensure no lingering artifacts remain.



314/4 2026/07/30 14:43 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/configfs.c Name:function_drop]

Results:
map[SourceCode: 651:	static void function_drop(
 652:			struct config_group *group,
 653:			struct config_item *item)
 654:	{
 655:		struct usb_function_instance *fi = to_usb_function_instance(item);
 656:		struct gadget_info *gi;
 657:	
 658:		gi = container_of(group, struct gadget_info, functions_group);
 659:	
 660:		mutex_lock(&gi->lock);
 661:		list_del(&fi->cfs_list);
 662:		mutex_unlock(&gi->lock);
 663:		config_item_put(item);
 664:	}
 SourceFile:drivers/usb/gadget/configfs.c]

315/4 2026/07/30 14:43 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 34027
							output: 47
							thoughts: 95
						

Thoughts:
**Analyzing the `config_item_put` Process**

Okay, so I'm looking at this `config_item_put(item)` call, and my understanding is that this will decrement the reference count of this function instance. Once that refcount hits zero, that's when the `usb_function_instance`'s release function gets triggered. Hang on, wasn't `usb_function_instance` actually a `config_group`? Right, it is. And its `ci_type` is linked to `f_midi2_func_type`. Alright, so if the release function is happening, I need to double-check what `f_midi2_func_type`'s release function is actually doing. We need to be sure that the release function in `f_midi2_func_type` is doing the cleanup properly.



316/4 2026/07/30 14:43 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_func_type]

Results:
map[SourceCode:2629:	static const struct config_item_type f_midi2_func_type = {
2630:		.ct_item_ops	= &f_midi2_item_ops,
2631:		.ct_group_ops	= &f_midi2_group_ops,
2632:		.ct_attrs	= f_midi2_attrs,
2633:		.ct_owner	= THIS_MODULE,
2634:	};
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

317/4 2026/07/30 14:43 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 34510
							output: 47
							thoughts: 11
						

Thoughts:
Okay, here's my interpretation of those thoughts, crafted with the understanding that I'm speaking to a fellow expert:

**Delving into MIDI Item Operations**

Alright, let's break down this `f_midi2_item_ops` function. Immediately, I'm thinking about the low-level MIDI data structures involved. Specifically, I imagine this deals with the fundamental manipulation of MIDI item events – perhaps insertion, deletion, modification, time-stretching, quantization, and the like, all the core operations one needs for serious MIDI editing. I'm assuming it handles the underlying data, probably dealing with the bitwise manipulation of MIDI messages efficiently. Is it optimized for specific hardware? Is it designed to be threading-friendly? We'll have to consider those aspects when we review the code. The main question on my mind is: Does this implementation provide sufficient flexibility for the wide range of use cases we need to support in this project?



318/4 2026/07/30 14:43 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_item_ops]

Results:
map[SourceCode:2620:	static const struct configfs_item_operations f_midi2_item_ops = {
2621:		.release	= f_midi2_opts_release,
2622:	};
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

319/4 2026/07/30 14:43 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 34857
							output: 47
							thoughts: 11
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:

**Analyzing `f_midi2_opts_release`**

Alright, let's dissect this. When I see `f_midi2_opts_release`, my mind immediately goes to the implications for a MIDI 2.0 implementation. This screams resource management, specifically dealing with the memory allocated for option structures related to MIDI 2.0 messages. It’s likely a function designed to free up those resources. I'm assuming "opts" refers to some kind of options struct – perhaps containing parameters, flags, or extended data related to specific MIDI 2.0 messages or features.

The "release" part indicates that this isn't about *allocating* the options. It's the inverse. We're talking about deallocating, clearing, or resetting these option data structures. Why? Likely because we're done processing a particular MIDI 2.0 message, a buffer is being freed, or some specific workflow phase is complete. We need to prevent memory leaks and ensure resources are handled correctly. I would look at the calling context of this function. I would be very interested to know *what* it's releasing. Knowing the structure of the "opts" struct is key. Are we talking about dynamic memory or references to internal data? Is there a need for zeroing memory here? If so, why and how? What's the potential for dangling pointers or double frees if there are linked structures within the options?

Given the context of MIDI 2.0, I'd expect this function to play a critical role in managing the new, potentially more complex, data payloads that MIDI 2.0 introduces, especially for features that add more parameters, such as the increased resolution of new 2.0 messages. The efficiency of this function is going to be important to prevent processing delays. A poorly implemented `f_midi2_opts_release` could quickly become a bottleneck in time-critical MIDI processing pipelines. So, I would want to ensure it is very performant. I would also investigate any error handling associated with this release. What happens if release fails?



320/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_opts_release]

Results:
map[SourceCode:2613:	static void f_midi2_opts_release(struct config_item *item)
2614:	{
2615:		struct f_midi2_opts *opts = to_f_midi2_opts(item);
2616:	
2617:		usb_put_function_instance(&opts->func_inst);
2618:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

321/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 35510
							output: 41
							thoughts: 10
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:

**Deep Dive into `usb_put_function_instance`**

Right, let's unpack `usb_put_function_instance`. My understanding is that this is where we're going to be freeing up resources associated with a USB function instance.  We're assuming it's been initialized and allocated elsewhere, likely by a framework or specific driver.  The critical aspect here is ensuring proper cleanup.  We need to look carefully for:

*   **Reference Counting:** Is this a reference-counted structure? If so, we're likely decrementing a counter, and the actual deallocation might only happen when it hits zero. This is crucial to prevent double-frees or prematurely freeing resources that are still in use by other parts of the system. I need to trace back to where the instance was initially created (`usb_get_function_instance` or equivalent) to confirm the reference counting scheme.
*   **Resource Deallocation:** What specific resources are being managed within this function instance? Think endpoints, descriptors, possibly control requests. We must ensure each resource is freed in the correct order, avoiding dangling pointers.  I'll need to know which internal structures it handles and follow the freeing logic.
*   **Error Handling:** What happens if deallocation fails?  Are there checks for the return values of lower-level free functions? Robust error handling is essential, because a failure here could lead to memory leaks or, worse, system instability. I'd expect to see some logging, but importantly, do we have any back-off mechanisms? If not, why not?
*   **Synchronization:** Are there any concurrent accesses to the function instance data?  This is a critical area.  We'll need to check for any mutexes or spinlocks protecting the data structure. Improper locking could result in race conditions and data corruption.  The code's context within the USB stack will determine what synchronization primitives are appropriate.
*   **Callback Handling:** Does this function instance have any associated callbacks or event handlers? If so, we need to consider how these are unregistered or deactivated during the cleanup process to avoid use-after-free conditions. Pay special attention to the order in which callbacks are disabled relative to other resource deallocations. This is typically a major source of bugs.
*   **Device State:** The device state at the time of calling `usb_put_function_instance` will need consideration. If the device has been disconnected or reset, there may be special considerations for deallocating resources that can no longer be reached.

In essence, `usb_put_function_instance` is a critical function, potentially right at the heart of our USB system's reliability, and it demands thorough analysis to ensure we're not introducing vulnerabilities or inefficiencies.



322/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/functions.c Name:usb_put_function_instance]

Results:
map[SourceCode:  69:	void usb_put_function_instance(struct usb_function_instance *fi)
  70:	{
  71:		struct module *mod;
  72:	
  73:		if (!fi)
  74:			return;
  75:	
  76:		mod = fi->fd->mod;
  77:		fi->free_func_inst(fi);
  78:		module_put(mod);
  79:	}
 SourceFile:drivers/usb/gadget/functions.c]

323/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 36316
							output: 47
							thoughts: 156
						

Thoughts:
**My Analysis of the USB MIDI Function Instance Cleanup**

Okay, so `usb_put_function_instance` is the key. That call triggers `fi->free_func_inst(fi);`. Right, and for `f_midi2`, `free_func_inst` translates to `f_midi2_free_inst`. So far, so good – the code is calling `f_midi2_free_inst`. That's where we added `configfs_remove_default_groups(&opts->func_inst.group);`. Excellent! That's precisely what we need to correctly decrement the reference counts of those default groups. Problem solved... or is it?

Hmm, I need to consider a potential edge case. What if `f_midi2_alloc_inst` fails *after* a successful `configfs_add_default_group`? We could have a memory leak situation. Best to revisit `f_midi2_alloc_inst` and check my assumptions. Let's dig back into that code.



324/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_alloc_inst]

Results:
map[SourceCode:2646:	/* gadget alloc_inst */
2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
2655:		if (!opts)
2656:			return ERR_PTR(-ENOMEM);
2657:	
2658:		mutex_init(&opts->lock);
2659:		opts->func_inst.free_func_inst = f_midi2_free_inst;
2660:		opts->info.process_ump = true;
2661:		opts->info.static_block = true;
2662:		opts->info.num_reqs = 32;
2663:		opts->info.req_buf_size = 512;
2664:	
2665:		/* create the default ep */
2666:		ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
2667:		if (ret) {
2668:			kfree(opts);
2669:			return ERR_PTR(ret);
2670:		}
2671:	
2672:		/* create the default block */
2673:		ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
2674:		if (ret) {
2675:			kfree(ep_opts);
2676:			kfree(opts);
2677:			return ERR_PTR(ret);
2678:		}
2679:	
2680:		/* set up the default MIDI1 (that is mandatory) */
2681:		block_opts->info.midi1_num_groups = 1;
2682:	
2683:		config_group_init_type_name(&opts->func_inst.group, "",
2684:					    &f_midi2_func_type);
2685:	
2686:		config_group_init_type_name(&ep_opts->group, "ep.0",
2687:					    &f_midi2_ep_type);
2688:		configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
2689:	
2690:		config_group_init_type_name(&block_opts->group, "block.0",
2691:					    &f_midi2_block_type);
2692:		configfs_add_default_group(&block_opts->group, &ep_opts->group);
2693:	
2694:		return &opts->func_inst;
2695:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

325/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 37575
							output: 49
							thoughts: 212
						

Thoughts:
**Analyzing Potential Resource Leaks in the MIDI2 ConfigFS Implementation**

Okay, so I'm looking at this `f_midi2_alloc_inst` function, and the way it interacts with `configfs_add_default_group`. I know that `configfs_add_default_group` is designed to be infallible; it's a `void` return, so there's no way it can actually fail. That means, following that call, `f_midi2_alloc_inst` *shouldn't* fail due to the `configfs_add_default_group` call itself.

But wait a minute... what about `config_group_init_type_name`? That one also returns `void`. Damn, it looks like there aren't any failure paths *directly* after `configfs_add_default_group` either. This seems a little too clean...

I need to make sure there aren't any subtle leaks elsewhere in `f_midi2.c` related to configfs group allocations. Let's do a quick scan of the code for any other points where we are allocating configfs groups. Okay, it looks like `f_midi2_opts_ep_make` and `f_midi2_opts_block_make` are the other key functions that allocate these groups. These are triggered by configfs when the user uses `mkdir` to create things.

Now, when a user removes those created groups using `rmdir`, configfs calls `f_midi2_opts_ep_drop` and `f_midi2_opts_block_drop`, respectively. So, if we are properly dropping them, there is no leak. Let's start by checking `f_midi2_opts_block_drop`.



326/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_opts_block_drop]

Results:
map[SourceCode:2396:	/* drop_item callback for a block */
2397:	static void
2398:	f_midi2_opts_block_drop(struct config_group *group, struct config_item *item)
2399:	{
2400:		struct f_midi2_block_opts *block_opts = to_f_midi2_block_opts(item);
2401:	
2402:		mutex_lock(&block_opts->ep->opts->lock);
2403:		block_opts->ep->blks[block_opts->id] = NULL;
2404:		mutex_unlock(&block_opts->ep->opts->lock);
2405:		config_item_put(item);
2406:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

327/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 38450
							output: 47
							thoughts: 419
						

Thoughts:
**My Analysis of the MIDI2 Driver Cleanup**

Okay, so I've been thinking about this refcount issue in the MIDI2 driver and the memory leaks associated with it. From what I can see, when we're dealing with dynamically created groups, dropping the refcount correctly triggers the `f_midi2_block_opts_release` function, and this in turn, frees the `block_opts` structure. Good. That part is working as expected. This means our dynamically created groups are being freed correctly.

The problem, as I understand it, seems to be isolated to those default groups - the ones that aren't automatically released by configfs. Thinking it through, are there any other default groups? No, it's just `ep.0` and `block.0`.

Let's quickly review that fix. I'm going over it again to make sure I've got a solid handle on it:

```c
static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group);
	kfree(opts->info.iface_name);
	kfree(opts);
}
```

```c
static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item));
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
}
```

This perfectly aligns with the initial explanation and the proposed solution. We're using `configfs_remove_default_groups` to address those default groups. This is the correct approach.

Now, I need to confirm something. Is `configfs_remove_default_groups` safe to call if there *aren't* any default groups? Let me check… yep, it verifies if the list is empty before doing anything. Good, that's reassuring.

Wait... I see `to_config_group(item)` is used in `f_midi2_ep_opts_release`. Just checking, is `item` embedded in a `struct config_group`? Let me look at `struct f_midi2_ep_opts` to be sure... Okay, all good. The plan works. I feel confident in this.



328/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_ep_opts]

Results:
map[SourceCode:  59:	struct f_midi2_ep_opts {
  60:		struct config_group group;
  61:		unsigned int index;
  62:		struct f_midi2_ep_info info;
  63:		struct f_midi2_block_opts *blks[SNDRV_UMP_MAX_BLOCKS];
  64:		struct f_midi2_opts *opts;
  65:	};
 SourceFile:drivers/usb/gadget/function/u_midi2.h]

329/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 39648
							output: 37
							thoughts: 61
						

Thoughts:
Okay, let me think this through.

**Analyzing the `configfs` Structure**

Right, so `group` is definitely the starting point. And if I recall correctly, `to_config_group(item)` is where we're going to retrieve the `config_group` struct from a given item. That's going to use `container_of(item, struct config_group, cg_item)`. Okay, that makes sense. We're using the member `cg_item` to get a pointer to the containing structure. Wait a second, just need to be sure... I believe that `to_config_group` itself is defined within `include/linux/configfs.h`. Yep, good to confirm that.



330/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:include/linux/configfs.h Name:to_config_group]

Results:
map[SourceCode:  90:	static inline struct config_group *to_config_group(struct config_item *item)
  91:	{
  92:		return item ? container_of(item,struct config_group,cg_item) : NULL;
  93:	}
 SourceFile:include/linux/configfs.h]

331/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 40001
							output: 40
							thoughts: 351
						

Thoughts:
**Reviewing the `configfs_remove_default_groups` Implementation and Scope**

Okay, the initial fix is confirmed. Now, my focus shifts to ensuring thoroughness. Are there any other locations within the relevant codebase where a similar oversight might exist? Specifically, is there anywhere else in the `f_midi2` code that should call `configfs_remove_default_groups`? Let's consider `f_midi2_block_opts_release`. Does this function involve any default groups? No, it looks like `f_midi2_block_opts_create` doesn't call `configfs_add_default_group` either.

The next question is, are there any other functions in this module that interact with default groups? Let me scan `f_midi2.c` for `configfs_add_default_group`. I've already done that, and it's only called within `f_midi2_alloc_inst`.

Alright, I should briefly consider if this type of bug is common. Based on the prompt, it seems that I am only supposed to check similar cases within the *same* file. We're not attempting a kernel-wide fix, just local improvements. Given I've already reviewed all instances of `configfs_add_default_group` in `f_midi2.c`, I believe I've met the prompt requirements.

Hmm, one last consideration... what if `f_midi2_ep_opts_release` is called for a dynamically created endpoint, something like `ep.1`? Do those have default groups? Ah, dynamically created endpoints don't have default groups, so that's not a concern. Now, will `configfs_remove_default_groups` even *handle* being called with no default groups? Let me quickly review the implementation to be sure.



332/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/dir.c Name:configfs_remove_default_groups]

Results:
map[SourceCode: 748:	void configfs_remove_default_groups(struct config_group *group)
 749:	{
 750:		struct config_group *g, *n;
 751:	
 752:		list_for_each_entry_safe(g, n, &group->default_groups, group_entry) {
 753:			list_del(&g->group_entry);
 754:			config_item_put(&g->cg_item);
 755:		}
 756:	}
 SourceFile:fs/configfs/dir.c]

333/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 40958
							output: 41
							thoughts: 59
						

Thoughts:
**Analyzing Group Initialization**

Okay, so I'm looking at this code and it's looping through `group->default_groups`. Pretty straightforward. If that list is empty, it just skips over the whole thing, which is fine, no big deal. But then a question pops up: hold on, what about dynamically created groups? Is `group->default_groups` properly initialized for *those*? I've got to make sure this isn't leaving things in a weird state. Time to double-check the `config_group_init_type_name` function to see how those dynamic groups are actually set up initially. I need to understand that initialization sequence to be confident.



334/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/item.c Name:config_group_init_type_name]

Results:
map[SourceCode:  92:	void config_group_init_type_name(struct config_group *group, const char *name,
  93:				 const struct config_item_type *type)
  94:	{
  95:		config_item_set_name(&group->cg_item, "%s", name);
  96:		group->cg_item.ci_type = type;
  97:		config_group_init(group);
  98:	}
 SourceFile:fs/configfs/item.c]

335/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 41350
							output: 37
							thoughts: 8
						

Thoughts:
Okay, here's my summary, in the first person, as an expert in my field, based on the implied task of summarizing thoughts related to a `config_group_init` process (though I have no specific text, I'm inferring from the function name what the focus would likely be):

**Diving Deep into Initialization & Configuration Groups**

Alright, so the core of what's probably on my mind here is the *initialization* of a configuration group. We're talking about a process that, based on the function naming, is dedicated to setting up a distinct collection of configuration parameters. My first instinct is to think about the design considerations. What's the goal of this `config_group_init`? Is it to create a new configuration, or to prepare an existing one for use? Understanding the intended usage scenario is key.

Then I get into the nuts and bolts of the function. I'm immediately running through the necessary steps in my head: memory allocation for the config group data structure, setting default values (or loading them from some source), handling any required dependencies between parameters, and validating initial inputs. What's the error handling strategy? Should it return an error code if something goes wrong, or use exceptions, or a combination? We need robust error handling.

I'm also considering the implications for multi-threaded applications. Is this initialization function thread-safe? Does it need synchronization primitives to protect shared resources? Performance is always a factor, so I'm thinking about efficient algorithms for copying or initializing data structures, especially if these configs are large. We need to be able to use the configs quickly, so we can't let initialization time drag down our execution.

From a practical perspective, I start contemplating how this initialization ties into the broader application architecture. Is `config_group_init` a low-level utility, or part of a higher-level configuration management framework? What are the integration points with other modules and components? What kind of external data sources does it interact with? The data will need to be accessible and easily used by any other feature or functionality.

Finally, I'm thinking about testability. How can I write unit tests for `config_group_init` to ensure it works correctly under various conditions? What are the edge cases I need to consider? I'll probably be thinking of how to mock dependencies and verify that the config group is initialized to a predictable state. I need to be able to quickly test and identify any issues or bugs in the initialization.



336/4 2026/07/30 14:44 tool codesearch-definition-source
0m Args:
map[ContextFile:fs/configfs/item.c Name:config_group_init]

Results:
map[SourceCode: 153:	/**
 154:	 *	config_group_init - initialize a group for use
 155:	 *	@group:	config_group
 156:	 */
 157:	void config_group_init(struct config_group *group)
 158:	{
 159:		config_item_init(&group->cg_item);
 160:		INIT_LIST_HEAD(&group->cg_children);
 161:		INIT_LIST_HEAD(&group->default_groups);
 162:	}
 SourceFile:fs/configfs/item.c]

337/4 2026/07/30 14:44 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 42095
							output: 47
							thoughts: 355
						

Thoughts:
**Reviewing the MIDI2 Module Cleanup**

Okay, so I've confirmed that `INIT_LIST_HEAD(&group->default_groups);` *is* indeed called. That means `group->default_groups` is initialized correctly and should be empty when we start. Therefore, running `configfs_remove_default_groups` on a dynamically created group should be entirely safe. No issues there.

Let me just quickly re-examine the code changes to be absolutely sure. Okay, here we have:

```c
static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group);
	kfree(opts->info.iface_name);
	kfree(opts);
}
```

```c
static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item));
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
}
```

Now, hold on... is there anything I'm missing? Ah, wait a minute! What about `f_midi2_free_inst`? Is there a possibility that `f_midi2_alloc_inst` could fail somewhere down the line and directly call `kfree(opts)` *without* calling `f_midi2_free_inst` first, thereby bypassing the necessary `configfs_remove_default_groups` cleanup? I'd better double-check `f_midi2_alloc_inst` just to be completely certain.



338/4 2026/07/30 14:45 tool codesearch-definition-source
0m Args:
map[ContextFile:drivers/usb/gadget/function/f_midi2.c Name:f_midi2_alloc_inst]

Results:
map[SourceCode:2646:	/* gadget alloc_inst */
2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
2655:		if (!opts)
2656:			return ERR_PTR(-ENOMEM);
2657:	
2658:		mutex_init(&opts->lock);
2659:		opts->func_inst.free_func_inst = f_midi2_free_inst;
2660:		opts->info.process_ump = true;
2661:		opts->info.static_block = true;
2662:		opts->info.num_reqs = 32;
2663:		opts->info.req_buf_size = 512;
2664:	
2665:		/* create the default ep */
2666:		ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
2667:		if (ret) {
2668:			kfree(opts);
2669:			return ERR_PTR(ret);
2670:		}
2671:	
2672:		/* create the default block */
2673:		ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
2674:		if (ret) {
2675:			kfree(ep_opts);
2676:			kfree(opts);
2677:			return ERR_PTR(ret);
2678:		}
2679:	
2680:		/* set up the default MIDI1 (that is mandatory) */
2681:		block_opts->info.midi1_num_groups = 1;
2682:	
2683:		config_group_init_type_name(&opts->func_inst.group, "",
2684:					    &f_midi2_func_type);
2685:	
2686:		config_group_init_type_name(&ep_opts->group, "ep.0",
2687:					    &f_midi2_ep_type);
2688:		configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
2689:	
2690:		config_group_init_type_name(&block_opts->group, "block.0",
2691:					    &f_midi2_block_type);
2692:		configfs_add_default_group(&block_opts->group, &ep_opts->group);
2693:	
2694:		return &opts->func_inst;
2695:	}
 SourceFile:drivers/usb/gadget/function/f_midi2.c]

339/4 2026/07/30 14:45 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 43771
							output: 30
							thoughts: 974
						

Thoughts:
**Analysis of Memory Management in the MIDI2 ConfigFS Implementation**

Okay, let's break this down. My primary concern is ensuring that we're properly freeing dynamically allocated memory, especially in the context of `configfs`. It's all about reference counting and making sure we don't leak resources.

First, I looked at what happens when `f_midi2_ep_opts_create` fails. It calls `kfree(opts)`. At that point, the `opts->func_inst.group.default_groups` isn't initialized, so no problem there, `kfree` is perfectly safe because `configfs_remove_default_groups` isn't called. Similarly, if `f_midi2_block_opts_create` fails, it calls `kfree(ep_opts)` and `kfree(opts)`. The same logic applies: `ep_opts->group.default_groups` isn't initialized, so again, it's safe.

Then I realized that `config_group_init_type_name` initializes `default_groups`. This is called *after* `f_midi2_block_opts_create`. Therefore, if `f_midi2_block_opts_create` fails, the `default_groups` *aren't* initialized, and `kfree` is called directly, which is still safe. We are fine.

However, I started thinking, what about `f_midi2_free_inst`? That's called when the function instance is freed. Crucially, `f_midi2_alloc_inst` has already succeeded by this point, so `default_groups` *are* initialized. This means that calling `configfs_remove_default_groups` in `f_midi2_free_inst` is safe, and *necessary*.

Now, is `f_midi2_free_inst` called anywhere else? No, it's assigned to `opts->func_inst.free_func_inst` and is only called by `usb_put_function_instance`. So, it's only ever called when the function instance is freed, as intended.

Next, `f_midi2_ep_opts_release` needs examining. It's assigned to `f_midi2_ep_item_ops.release`. This is called by configfs when the refcount of the EP group reaches 0. Now, the `default_groups` are initialized, either by `config_group_init_type_name` in `f_midi2_alloc_inst` or by `f_midi2_opts_ep_make`. This implies `configfs_remove_default_groups` is safe to call.

The question then becomes, what if `f_midi2_opts_ep_make` fails *after* `config_group_init_type_name`? It doesn't. The code is structured like this:

```c
	ret = f_midi2_ep_opts_create(opts, index, &ep_opts);
	if (ret)
		return ERR_PTR(ret);

	config_group_init_type_name(&ep_opts->group, name, &f_midi2_ep_type);
	return &ep_opts->group;
```

So, it's safe because `config_group_init_type_name` is always called *before* the return that might cause a failure.

The same analysis goes for `f_midi2_opts_block_make`:
```c
	ret = f_midi2_block_opts_create(ep_opts, blk, &block_opts);
	if (ret)
		return ERR_PTR(ret);

	config_group_init_type_name(&block_opts->group, name,
				    &f_midi2_block_type);
	return &block_opts->group;
```
It's fine.

**Conclusion:** I think the fix is complete and correct. We need to add `configfs_remove_default_groups` to `f_midi2_free_inst` and `f_midi2_ep_opts_release` to correctly drop the references to the default groups. This ensures the dynamically allocated memory for the default groups is freed when the parent group is destroyed. This explicitly unrolls the default groups. Since the `ep.0` and `block.0` groups *already* have release callbacks, `configfs_remove_default_groups` will correctly call them, freeing memory in the right order. Critically, dynamically created groups (e.g. `ep.1`) don't have default groups, but `configfs_remove_


340/4 2026/07/30 14:45 tool patch-diff
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2466,20 +2466,21 @@ static struct configfs_attribute *f_midi2_ep_attrs[] = {
 	&f_midi2_ep_opts_attr_family,
 	&f_midi2_ep_opts_attr_model,
 	&f_midi2_ep_opts_attr_sw_revision,
 	NULL,
 };
 
 static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
 }
 
 static const struct configfs_item_operations f_midi2_ep_item_ops = {
 	.release	= f_midi2_ep_opts_release,
 };
 
 static const struct configfs_group_operations f_midi2_ep_group_ops = {
@@ -2632,20 +2633,21 @@ static const struct config_item_type f_midi2_func_type = {
 	.ct_attrs	= f_midi2_attrs,
 	.ct_owner	= THIS_MODULE,
 };
 
 static void f_midi2_free_inst(struct usb_function_instance *f)
 {
 	struct f_midi2_opts *opts;
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 
 /* gadget alloc_inst */
 static struct usb_function_instance *f_midi2_alloc_inst(void)
 {
 	struct f_midi2_opts *opts;
 	struct f_midi2_ep_opts *ep_opts;
 	struct f_midi2_block_opts *block_opts;
]

341/4 2026/07/30 14:45 llm patch-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 46447
							output: 390
							thoughts: 14
						

Thoughts:
Here's my take on the situation:

**Finalizing the Response: It's Ready**

Alright, the diff is absolutely spot-on. No lingering doubts, no need for further tweaking – everything aligns perfectly. The analysis is complete, the integration is smooth, and the potential implications have been rigorously considered. I'm satisfied; I can confidently move forward. It's time to craft the definitive response, integrating all the insights and drawing a clear and concise conclusion. I'm ready to articulate the final answer, knowing I've covered all the necessary bases.



342/3 2026/07/30 14:45 action test-patch
20m Results:
map[PatchDiff:diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2473,6 +2473,7 @@ static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
@@ -2639,6 +2640,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 TestError:]

343/1 2026/07/30 15:05 action apply-patch
0m Results:
map[]

344/1 2026/07/30 15:05 action init-style-items
0m Results:
map[StyleItems:<nil>]

345/1 2026/07/30 15:05 loop
3m
346/2 2026/07/30 15:05 iteration 0
3m
347/3 2026/07/30 15:05 agent patch-formatter
3m Model:
good-balanced

Instruction:
You are an expert Linux kernel developer tasked with formatting a kernel patch.
Your objective is purely formatting: you must ensure the patch complies with the kernel's coding style,
conforms to the surrounding code rules, and passes checkpatch.pl, while preserving the code logic exactly as it is.
You should stop once the requested formatting changes are done and checkpatch.pl is happy.
Do not question the requested changes unless they are obviously wrong.
If the code already conforms to the requested changes, surrounding code rules,
and checkpatch.pl is happy, you should just finish your task.

WARNING: The clang-format tool may break the formatting of the surrounding code (like manual alignment).
Use it with caution. We want to make the change fit into the existing formatting as much as possible.

Prefer calling several tools at the same time to save round-trips.

Prompt:
The current patch diff is:

diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2473,6 +2473,7 @@ static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
@@ -2639,6 +2640,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }










Use the provided tools to format the patch.

Reply:
The patch has been analyzed and verified. It is already fully compliant with the Linux kernel's coding style, conforms to the surrounding code rules, and passes `checkpatch.pl` with zero errors and zero warnings:

```
total: 0 errors, 0 warnings, 14 lines checked

Your patch has no obvious style problems and is ready for submission.
```

No further formatting changes are required.

348/4 2026/07/30 15:05 llm patch-formatter
0m Model:
gemini-3.5-flash

Tokens:
							input: 4637
							output: 39
							thoughts: 50
						

Thoughts:
**Kernel Patch Formatting - My Approach**

Okay, so the user wants a nicely formatted kernel patch, got it. My immediate thought is to make sure we do this right. Before I even look at the formatting though, let's establish a baseline of quality. I need to ensure the patch itself is sound and meets all the required checks.

First things first, I will use `checkpatch` to do a thorough code style and linting analysis. That way I have a clear report of issues with the provided patch, before I start formatting. Then, *after* `checkpatch` is clean, I can look at the diff itself. I'll use `patch-diff` to get a precise view of the modifications made. Armed with both, I'll move forward.



349/4 2026/07/30 15:06 tool patch-diff
0m Error:
missing argument "File"

Args:
map[file:drivers/usb/gadget/function/f_midi2.c]

350/4 2026/07/30 15:06 tool checkpatch
0m Results:
map[Output:total: 0 errors, 0 warnings, 14 lines checked

Your patch has no obvious style problems and is ready for submission.
]

351/4 2026/07/30 15:06 llm patch-formatter
0m Model:
gemini-3.5-flash

Tokens:
							input: 4946
							output: 88
							thoughts: 245
						

Thoughts:
**Analyzing the `patch-diff` Function and Associated Code**

Okay, so I'm looking at this `patch-diff` function and it seems the documentation has a minor discrepancy I need to sort out. It *says* the `File` parameter is optional, that if empty, the diff will include all changes. But the schema is indicating that `File` is *required*, but can be an empty string, `"`.  That's a bit confusing, but I think I've got it - I can call the function with either an empty string for the `File` parameter, or a specific filename.  I'll test it out both ways. For the specific file, I'll use `"drivers/usb/gadget/function/f_midi2.c"`.

Before that, I ran `checkpatch.pl` on my changes, and it's reporting zero errors and warnings, which is always encouraging! The output also mentioned "14 lines checked".

To be thorough, let's now examine that specific file, `"drivers/usb/gadget/function/f_midi2.c"` around the lines of 2473 and 2639, just to double-check formatting and ensure I haven't introduced any subtle style violations that `checkpatch.pl` might have missed. I'll read around those lines for any context that might raise a flag.



352/4 2026/07/30 15:06 tool read-file
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c FirstLine:2460 LineCount:30]

Results:
map[Contents:2460:	static struct configfs_attribute *f_midi2_ep_attrs[] = {
2461:		&f_midi2_ep_opts_attr_protocol,
2462:		&f_midi2_ep_opts_attr_protocol_caps,
2463:		&f_midi2_ep_opts_attr_ep_name,
2464:		&f_midi2_ep_opts_attr_product_id,
2465:		&f_midi2_ep_opts_attr_manufacturer,
2466:		&f_midi2_ep_opts_attr_family,
2467:		&f_midi2_ep_opts_attr_model,
2468:		&f_midi2_ep_opts_attr_sw_revision,
2469:		NULL,
2470:	};
2471:	
2472:	static void f_midi2_ep_opts_release(struct config_item *item)
2473:	{
2474:		struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
2475:	
2476:		kfree(opts->info.ep_name);
2477:		kfree(opts->info.product_id);
2478:		kfree(opts);
2479:	}
2480:	
2481:	static const struct configfs_item_operations f_midi2_ep_item_ops = {
2482:		.release	= f_midi2_ep_opts_release,
2483:	};
2484:	
2485:	static const struct configfs_group_operations f_midi2_ep_group_ops = {
2486:		.make_group	= f_midi2_opts_block_make,
2487:		.drop_item	= f_midi2_opts_block_drop,
2488:	};
2489:	
]

353/4 2026/07/30 15:06 tool read-file
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c FirstLine:2625 LineCount:30]

Results:
map[Contents:2625:		.make_group	= f_midi2_opts_ep_make,
2626:		.drop_item	= f_midi2_opts_ep_drop,
2627:	};
2628:	
2629:	static const struct config_item_type f_midi2_func_type = {
2630:		.ct_item_ops	= &f_midi2_item_ops,
2631:		.ct_group_ops	= &f_midi2_group_ops,
2632:		.ct_attrs	= f_midi2_attrs,
2633:		.ct_owner	= THIS_MODULE,
2634:	};
2635:	
2636:	static void f_midi2_free_inst(struct usb_function_instance *f)
2637:	{
2638:		struct f_midi2_opts *opts;
2639:	
2640:		opts = container_of(f, struct f_midi2_opts, func_inst);
2641:	
2642:		kfree(opts->info.iface_name);
2643:		kfree(opts);
2644:	}
2645:	
2646:	/* gadget alloc_inst */
2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
]

354/4 2026/07/30 15:06 llm patch-formatter
0m Model:
gemini-3.5-flash

Tokens:
							input: 6587
							output: 30
							thoughts: 81
						

Thoughts:
**Analyzing the Current Patch and Repository Status**

Okay, first things first, let me pull up the user's provided patch diff. Let's see... the user has stated: "The current patch diff is: ...". Right, got it.

Now, before I start integrating anything or making any recommendations, I need to know: has this patch already been applied? Is it redundant? Let's check the repository's status. I'll need to use `patch-diff` and test with the appropriate file locations. Let's start with a blanket check, using `File: ""`, and then if necessary I'll drill down to specifically check `drivers/usb/gadget/function/f_midi2.c`, depending on the results. Gotta be methodical about this.



355/4 2026/07/30 15:07 tool patch-diff
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2466,20 +2466,21 @@ static struct configfs_attribute *f_midi2_ep_attrs[] = {
 	&f_midi2_ep_opts_attr_family,
 	&f_midi2_ep_opts_attr_model,
 	&f_midi2_ep_opts_attr_sw_revision,
 	NULL,
 };
 
 static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
 }
 
 static const struct configfs_item_operations f_midi2_ep_item_ops = {
 	.release	= f_midi2_ep_opts_release,
 };
 
 static const struct configfs_group_operations f_midi2_ep_group_ops = {
@@ -2632,20 +2633,21 @@ static const struct config_item_type f_midi2_func_type = {
 	.ct_attrs	= f_midi2_attrs,
 	.ct_owner	= THIS_MODULE,
 };
 
 static void f_midi2_free_inst(struct usb_function_instance *f)
 {
 	struct f_midi2_opts *opts;
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 
 /* gadget alloc_inst */
 static struct usb_function_instance *f_midi2_alloc_inst(void)
 {
 	struct f_midi2_opts *opts;
 	struct f_midi2_ep_opts *ep_opts;
 	struct f_midi2_block_opts *block_opts;
]

356/4 2026/07/30 15:07 llm patch-formatter
1m Model:
gemini-3.5-flash

Tokens:
							input: 7511
							output: 15
							thoughts: 384
						

Thoughts:
**My Assessment of the Patch's Status**

Alright, the patch is in the repository, that's a good start. My immediate concern is whether this is the *only* change that has been made. I need to make sure there are no other accidental modifications lurking, or any unexpected side-effects.

First, I'm going to rerun `checkpatch` just to be absolutely sure. Okay, the output looks clean: `total: 0 errors, 0 warnings, 14 lines checked`. It confirms: `"Your patch has no obvious style problems and is ready for submission."`

But even with a clean bill of health from `checkpatch`, I'm still feeling cautious. Let's take a closer look at the code snippets provided just to double-check:

```c
static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item));
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
}
```
and:
```c
static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group);
	kfree(opts->info.iface_name);
	kfree(opts);
}
```

The code seems fine, but there are potentially more changes. Let's make sure by going back to `git`.  I need to make sure I'm not overlooking anything. The key now is using `patch-diff` with `File: ""` to show *all* changes made. I'm going to run that command to get the definitive answer on whether there are any other unintended modifications associated with this patch. This is the only way to be completely sure.



357/4 2026/07/30 15:08 tool patch-diff
0m Args:
map[File:]

Results:
map[Output:diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2466,20 +2466,21 @@ static struct configfs_attribute *f_midi2_ep_attrs[] = {
 	&f_midi2_ep_opts_attr_family,
 	&f_midi2_ep_opts_attr_model,
 	&f_midi2_ep_opts_attr_sw_revision,
 	NULL,
 };
 
 static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
 }
 
 static const struct configfs_item_operations f_midi2_ep_item_ops = {
 	.release	= f_midi2_ep_opts_release,
 };
 
 static const struct configfs_group_operations f_midi2_ep_group_ops = {
@@ -2632,20 +2633,21 @@ static const struct config_item_type f_midi2_func_type = {
 	.ct_attrs	= f_midi2_attrs,
 	.ct_owner	= THIS_MODULE,
 };
 
 static void f_midi2_free_inst(struct usb_function_instance *f)
 {
 	struct f_midi2_opts *opts;
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 
 /* gadget alloc_inst */
 static struct usb_function_instance *f_midi2_alloc_inst(void)
 {
 	struct f_midi2_opts *opts;
 	struct f_midi2_ep_opts *ep_opts;
 	struct f_midi2_block_opts *block_opts;
]

358/4 2026/07/30 15:08 llm patch-formatter
0m Model:
gemini-3.5-flash

Tokens:
							input: 9035
							output: 86
							thoughts: 833
						

Thoughts:
**Analysis of the Provided Patch**

Okay, so the user has given me a patch, and my job is straightforward: ensure it adheres to kernel coding style, matches the surrounding code, and passes `checkpatch.pl`, without altering the logic. First, I verified that the changes *exactly* match the diff.

I was about to dive into a deeper style check, or even a full `checkpatch` run on the whole file, but hold on, let's go back and re-read the instructions! My focus is solely on formatting; I'm not supposed to question the changes unless they are obviously incorrect. If the requested changes are already compliant, I'm done.

A quick review of the surrounding code reveals the pattern for blank lines after variable declarations, specifically in `f_midi2_ep_opts_release` and `f_midi2_free_inst`. The patch *does* introduce that blank line in `f_midi2_free_inst`, matching what's already present in other similar functions. I even double-checked the *original* code for the same function to confirm the existing style.

I did, however, pause briefly to consider if there were other files or functions that might require similar changes, but the instructions are clear: if everything's good with this patch, I'm finished.

So, let's see... the instructions say, "If the code already conforms to the requested changes, surrounding code rules, and checkpatch.pl is happy, you should just finish your task." I've confirmed that the patch is applied, `checkpatch.pl` *should* be happy, and the formatting is exactly what's expected according to the surrounding code rules.

Just to be absolutely sure, I did a final scan for any stray trailing whitespace or other minor issues and, just for kicks, I ran `checkpatch` again, and indeed, it reported "0 errors, 0 warnings, 14 lines checked" and the delightful "Your patch has no obvious style problems and is ready for submission."

Fantastic! I'm completely satisfied that this patch is perfectly formatted and compliant. Time to give the user a clear and concise report.



359/3 2026/07/30 15:09 action test-patch-inplace
0m Results:
map[PatchDiff:diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2473,6 +2473,7 @@ static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
@@ -2639,6 +2640,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 TestError:]

360/3 2026/07/30 15:09 action run-checkpatch
0m Results:
map[CheckpatchOutput:total: 0 errors, 0 warnings, 14 lines checked

Your patch has no obvious style problems and is ready for submission.
 NeedRefinement:false]

361/1 2026/07/30 15:09 agent fixes-finder
2m Model:
best-expensive

Results:
map[FixesHash:29ee7a4dddd5caa18d1cef000f20c6af43f762f1]

Instruction:
You are an experienced Linux kernel developer tasked with identifying the commit
that introduced the bug being fixed. Identifying the correct buggy commit is crucial
for proper kernel maintenance (backporting to stable trees, etc.).

Your investigation strategy:
1. Examine the patch that fixes the bug. Use git tools (like git-log or git-blame)
   to trace the history of the lines or functions modified by the patch.
2. Analyze the stack trace in the crash report. Identify the key files and functions
   involved in the crash and investigate their history to see when the problematic
   logic was introduced.
3. Compare the bug explanation with the commit history to find the point where
   the described logic error first appeared.

A bug is typically introduced when a piece of code is first written, or when
a refactoring changed its logic in a way that introduced the bug.
Trace the history of relevant symbols or find when specific code patterns were introduced/removed.

You must provide exactly one bug-introducing commit hash.
If you are unable to confidently determine the bug-introducing commit after investigation,
return an empty string rather than guessing.

Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
The crash is:

2026/07/30 13:30:35 executed programs: 5
BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504 [inline]
    f_midi2_alloc_inst+0x80/0x2c0 drivers/usb/gadget/function/f_midi2.c:2666
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342 [inline]
    f_midi2_alloc_inst+0x16a/0x2c0 drivers/usb/gadget/function/f_midi2.c:2673
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF



The explanation of the root cause is:

The root cause of this memory leak is that the driver fails to drop the reference counts of its default configfs groups when the parent group is destroyed.

When a USB function instance for `midi2` is allocated via `f_midi2_alloc_inst()`, it dynamically allocates `ep_opts` and `block_opts` structures using `kzalloc_obj()`. These structures are then initialized as configfs groups and added as default groups to their respective parents:
- `ep.0` is added as a default group to the function instance group (`opts->func_inst.group`).
- `block.0` is added as a default group to the endpoint group (`ep_opts->group`).

When the user removes the configfs directory for the function instance (via `rmdir`), configfs removes the dentries for the default groups but **does not** automatically drop their reference counts. The responsibility of dropping the refcounts of default groups lies with the driver, typically by calling `configfs_remove_default_groups()` when the parent group is released.

However, `f_midi2_free_inst()` (which is called when the function instance's refcount reaches 0) only frees the `f_midi2_opts` structure and does not clean up its default groups. Similarly, `f_midi2_ep_opts_release()` does not clean up its default groups. As a result, the `ep_opts` and `block_opts` structures are leaked.

### How to fix it

To fix the leak, you need to explicitly remove the default groups and drop their reference counts before freeing the parent structures. This can be done by calling `configfs_remove_default_groups()` in the respective release functions.

1. In `f_midi2_free_inst()`, drop the default groups of the function instance (this will drop the refcount of `ep.0` and trigger `f_midi2_ep_opts_release`):
```c
static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group); /* ADD THIS */
	kfree(opts->info.iface_name);
	kfree(opts);
}
```

2. In `f_midi2_ep_opts_release()`, drop the default groups of the endpoint (this will drop the refcount of `block.0` and trigger `f_midi2_block_opts_release`):
```c
static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item)); /* ADD THIS */
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
}
```

With these changes, the hierarchy of default groups will be properly unrolled and freed when the function instance is destroyed, whether it's through configfs `rmdir` or an error path that directly calls `usb_put_function_instance()`.


The patch that fixes the bug is:

diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2473,6 +2473,7 @@ static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
@@ -2639,6 +2640,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }


Search for the commit(s) that introduced this bug.

362/2 2026/07/30 15:09 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 6539
							output: 45
							thoughts: 164
						

Thoughts:
**Pinpointing the Memory Leak in f_midi2.c**

Alright, let's get down to brass tacks. We've got a memory leak on our hands in `drivers/usb/gadget/function/f_midi2.c`, and my initial assessment points the finger at the absence of `configfs_remove_default_groups` within the `f_midi2_ep_opts_release` and `f_midi2_free_inst` functions. Clearly, we need to trace the lineage of this code to identify the offending commit.

My plan of attack is straightforward: I'll dive into the Git history of `drivers/usb/gadget/function/f_midi2.c`. I'm going to leverage `git log` to pinpoint the exact commits that brought `f_midi2_ep_opts_release` and `f_midi2_free_inst` into the fold. Knowing their genesis will illuminate when the potential oversight might have been introduced, and allow us to verify that hypothesis. With the relevant commit range identified, I can then zero in on any changes to memory management within those functions to find the culprit.



363/2 2026/07/30 15:09 tool git-log
0m Error:
SymbolName and PathPrefix cannot be used together

Args:
map[PathPrefix:drivers/usb/gadget/function/f_midi2.c SymbolName:f_midi2_free_inst]

Results:
map[Output:]

364/2 2026/07/30 15:09 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 7017
							output: 45
							thoughts: 14
						

Thoughts:
Okay, here's my summary, tailored as requested:

**Navigating the Codebase Effectively**

Right, let's see. Thinking through this, it feels like the most elegant approach to this particular problem involves a judicious pairing of tools. I need to be able to pinpoint a particular definition. `SourcePath` seems like the obvious starting point. I can use that to locate the file, the specific location in the filesystem. But, that's not enough on its own. I also need to be able to identify the correct code element within that file. That's where `SymbolName` comes in. Together, `SourcePath` and `SymbolName` offer a powerful and targeted way to home in on the specific piece of code I'm after. This combination should yield the exact location and definition I require. Yes, that's the path I should follow.



365/2 2026/07/30 15:09 tool git-log
0m Args:
map[SourcePath:drivers/usb/gadget/function/f_midi2.c SymbolName:f_midi2_free_inst]

Results:
map[Output:29ee7a4dddd5 usb: gadget: midi2: Add configfs support
8b645922b223 usb: gadget: Add support for USB MIDI 2.0 function driver
]

366/2 2026/07/30 15:09 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 7320
							output: 27
							thoughts: 35
						

Thoughts:
Okay, let's dive into commit `8b645922b223 usb: gadget: Add support for USB MIDI 2.0 function driver`.

**Analyzing the USB MIDI 2.0 Gadget Driver Commit**

Right, so I see this commit aims to introduce support for USB MIDI 2.0 within the gadget framework. This is crucial; USB MIDI 2.0 is the direction the industry is heading in, and if we're serious about our embedded music projects, this is a must-have. I need to understand how well they've implemented the new features.

First, I'll examine how they've structured the driver within the existing gadget framework. Are they using the standard USB descriptors effectively? Have they clearly separated the MIDI 2.0 specific parts from the generic USB transport layer? Good, clean separation is key for maintainability and future upgrades. I'll need to check the descriptor handling – does it accurately reflect the requirements of the MIDI 2.0 specification? Specifically, I'll be looking for support of Universal MIDI Packets (UMP) and any associated data formats.

Next, I'll want to assess the endpoint management. Are they leveraging the asynchronous transfer capabilities of USB 2.0 and/or 3.0? This is critical for low-latency MIDI data transmission. Ideally, they'll have optimized the buffering and interrupt handling to minimize overhead. I'll need to check the interrupt in and out functions to see if they are doing this correctly.

Finally, I'll check how they've handled error conditions and edge cases. MIDI, by its nature, is real-time. Losing a packet or introducing delays is unacceptable. Is the code robust to different clock speeds and USB transfer sizes? Are there sufficient error checks and recovery mechanisms in place? It's all about ensuring the system is rock solid. I need to be sure this is going to play well with all the other devices it may be connected to.



367/2 2026/07/30 15:09 tool git-show
0m Args:
map[Commit:8b645922b223]

Results:
map[Output:
Full output is too long, showing 1000 out of 1877 lines.

[commit 8b645922b22303cec4628dbbbf6c8553d1cdec87
 Author: Takashi Iwai <tiwai@suse.de>
 Date:   Tue Jul 25 08:22:00 2023 +0200
 
     usb: gadget: Add support for USB MIDI 2.0 function driver
     
     This patch adds the support for USB MIDI 2.0 gadget function driver.
     The driver emulates a USB MIDI 2.0 interface with one or more UMP
     Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
     handling MIDI 2.0 UMP packets.  When the function driver is bound, the
     driver creates an ALSA card object with UMP rawmidi devices.  This is
     a kind of loop-back where the incoming and upcoming UMP packets
     from/to the MIDI 2.0 UMP Endpoints are transferred as-is.  In
     addition, legacy (MIDI 1.0) rawmidi devices are created, so that
     legacy applications can work in the gadget side, too.
     
     When a USB MIDI 2.0 gadget interface appears, the connected host can
     use it with the snd-usb-audio driver where MIDI 2.0 support is
     enabled.  Both gadget and connected hosts will have the similar UMP
     Endpoint and Function Block (or Group Terminal Block) information.
     Slight differences are the direction and UI-hint bits; it's due to the
     nature of gadget driver, and the input/output direction is swapped in
     both sides (the input for gadget is the output for host, and vice
     versa).
     
     The driver supports the brand-new UMP v1.1 feature, including the UMP
     Stream message handling for providing UMP Endpoint and Function Block
     information as well as dealing with the MIDI protocol switch.  The
     driver responds to UMP Stream messages by itself.  OTOH, MIDI-CI
     message handling isn't implemented in the kernel driver; it should be
     processed in the user-space through the loopback UMP device.
     
     As of this patch, the whole configuration is fixed, providing only one
     bidirectional UMP Endpoint containing a single FB/GTB with a single
     UMP Group.  The configuration will be dynamically changeable in the
     following patches.
     
     The traditional MIDI 1.0 is still provided in the altset 0 (which is
     mandatory per spec).  But it's only about the configuration, and no
     actual I/O will be running for the altset 0 as of this patch.  The
     proper support MIDI 1.0 altset will follow in later patches, too.
     
     Signed-off-by: Takashi Iwai <tiwai@suse.de>
     Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
     Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
 index 336db8f92afa..b3592bcb0f96 100644
 --- a/drivers/usb/gadget/Kconfig
 +++ b/drivers/usb/gadget/Kconfig
 @@ -208,6 +208,9 @@ config USB_F_UVC
  config USB_F_MIDI
  	tristate
  
 +config USB_F_MIDI2
 +	tristate
 +
  config USB_F_HID
  	tristate
  
 @@ -436,6 +439,21 @@ config USB_CONFIGFS_F_MIDI
  	  connections can then be made on the gadget system, using
  	  ALSA's aconnect utility etc.
  
 +config USB_CONFIGFS_F_MIDI2
 +	bool "MIDI 2.0 function"
 +	depends on USB_CONFIGFS
 +	depends on SND
 +	select USB_LIBCOMPOSITE
 +	select SND_UMP
 +	select SND_UMP_LEGACY_RAWMIDI
 +	select USB_F_MIDI2
 +	help
 +	  The MIDI 2.0 function driver provides the generic emulated
 +	  USB MIDI 2.0 interface, looped back to ALSA UMP rawmidi
 +	  device on the gadget host. It supports UMP 1.1 spec and
 +	  responds UMP Stream messages for UMP Endpoint and Function
 +	  Block information / configuration.
 +
  config USB_CONFIGFS_F_HID
  	bool "HID function"
  	depends on USB_CONFIGFS
 diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile
 index 5d3a6cf02218..87917a7d4a9b 100644
 --- a/drivers/usb/gadget/function/Makefile
 +++ b/drivers/usb/gadget/function/Makefile
 @@ -44,6 +44,8 @@ usb_f_uvc-y			:= f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o
  obj-$(CONFIG_USB_F_UVC)		+= usb_f_uvc.o
  usb_f_midi-y			:= f_midi.o
  obj-$(CONFIG_USB_F_MIDI)	+= usb_f_midi.o
 +usb_f_midi2-y			:= f_midi2.o
 +obj-$(CONFIG_USB_F_MIDI2)	+= usb_f_midi2.o
  usb_f_hid-y			:= f_hid.o
  obj-$(CONFIG_USB_F_HID)		+= usb_f_hid.o
  usb_f_printer-y			:= f_printer.o
 diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
 new file mode 100644
 index 000000000000..848cb3150deb
 --- /dev/null
 +++ b/drivers/usb/gadget/function/f_midi2.c
 @@ -0,0 +1,1691 @@
 +// SPDX-License-Identifier: GPL-2.0+
 +/*
 + * f_midi2.c -- USB MIDI 2.0 class function driver
 + */
 +
 +#include <linux/device.h>
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/slab.h>
 +
 +#include <sound/core.h>
 +#include <sound/ump.h>
 +#include <sound/ump_msg.h>
 +
 +#include <linux/usb/ch9.h>
 +#include <linux/usb/gadget.h>
 +#include <linux/usb/audio.h>
 +#include <linux/usb/midi-v2.h>
 +
 +#include "u_f.h"
 +#include "u_midi2.h"
 +
 +struct f_midi2;
 +struct f_midi2_ep;
 +struct f_midi2_usb_ep;
 +
 +/* Context for each USB request */
 +struct f_midi2_req_ctx {
 +	struct f_midi2_usb_ep *usb_ep;	/* belonging USB EP */
 +	unsigned int index;		/* array index: 0-31 */
 +	struct usb_request *req;	/* assigned request */
 +};
 +
 +/* Resources for a USB Endpoint */
 +struct f_midi2_usb_ep {
 +	struct f_midi2 *card;		/* belonging card */
 +	struct f_midi2_ep *ep;		/* belonging UMP EP (optional) */
 +	struct usb_ep *usb_ep;		/* assigned USB EP */
 +	void (*complete)(struct usb_ep *usb_ep, struct usb_request *req);
 +	unsigned long free_reqs;	/* bitmap for unused requests */
 +	unsigned int num_reqs;		/* number of allocated requests */
 +	struct f_midi2_req_ctx *reqs;	/* request context array */
 +};
 +
 +/* Resources for UMP Function Block (and USB Group Terminal Block) */
 +struct f_midi2_block {
 +	struct f_midi2_block_info info;	/* FB info, copied from configfs */
 +	struct snd_ump_block *fb;	/* assigned FB */
 +	unsigned int gtb_id;		/* assigned GTB id */
 +	unsigned int string_id;		/* assigned string id */
 +};
 +
 +/* Resources for UMP Endpoint */
 +struct f_midi2_ep {
 +	struct snd_ump_endpoint *ump;	/* assigned UMP EP */
 +	struct f_midi2 *card;		/* belonging MIDI 2.0 device */
 +
 +	struct f_midi2_ep_info info;	/* UMP EP info, copied from configfs */
 +	unsigned int num_blks;		/* number of FBs */
 +	struct f_midi2_block blks[SNDRV_UMP_MAX_BLOCKS];	/* UMP FBs */
 +
 +	struct f_midi2_usb_ep ep_in;	/* USB MIDI EP-in */
 +	struct f_midi2_usb_ep ep_out;	/* USB MIDI EP-out */
 +};
 +
 +/* indices for USB strings */
 +enum {
 +	STR_IFACE = 0,
 +	STR_GTB1 = 1,
 +};
 +
 +/* 1-based GTB id to string id */
 +#define gtb_to_str_id(id)	(STR_GTB1 + (id) - 1)
 +
 +/* operation mode */
 +enum {
 +	MIDI_OP_MODE_UNSET,	/* no altset set yet */
 +	MIDI_OP_MODE_MIDI1,	/* MIDI 1.0 (altset 0) is used */
 +	MIDI_OP_MODE_MIDI2,	/* MIDI 2.0 (altset 1) is used */
 +};
 +
 +/* Resources for MIDI 2.0 Device */
 +struct f_midi2 {
 +	struct usb_function func;
 +	struct usb_gadget *gadget;
 +	struct snd_card *card;
 +
 +	/* MIDI 1.0 in/out USB EPs */
 +	struct f_midi2_usb_ep midi1_ep_in;
 +	struct f_midi2_usb_ep midi1_ep_out;
 +
 +	int midi_if;			/* USB MIDI interface number */
 +	int operation_mode;		/* current operation mode */
 +
 +	spinlock_t queue_lock;
 +
 +	struct f_midi2_card_info info;	/* card info, copied from configfs */
 +
 +	unsigned int num_eps;
 +	struct f_midi2_ep midi2_eps[MAX_UMP_EPS];
 +
 +	unsigned int total_blocks;	/* total number of blocks of all EPs */
 +	struct usb_string *string_defs;
 +	struct usb_string *strings;
 +};
 +
 +#define func_to_midi2(f)	container_of(f, struct f_midi2, func)
 +
 +/* get EP name string */
 +static const char *ump_ep_name(const struct f_midi2_ep *ep)
 +{
 +	return ep->info.ep_name ? ep->info.ep_name : "MIDI 2.0 Gadget";
 +}
 +
 +/* get EP product ID string */
 +static const char *ump_product_id(const struct f_midi2_ep *ep)
 +{
 +	return ep->info.product_id ? ep->info.product_id : "Unique Product ID";
 +}
 +
 +/* get FB name string */
 +static const char *ump_fb_name(const struct f_midi2_block_info *info)
 +{
 +	return info->name ? info->name : "MIDI 2.0 Gadget I/O";
 +}
 +
 +/*
 + * USB Descriptor Definitions
 + */
 +/* GTB header descriptor */
 +static struct usb_ms20_gr_trm_block_header_descriptor gtb_header_desc = {
 +	.bLength =		sizeof(gtb_header_desc),
 +	.bDescriptorType =	USB_DT_CS_GR_TRM_BLOCK,
 +	.bDescriptorSubtype =	USB_MS_GR_TRM_BLOCK_HEADER,
 +	.wTotalLength =		__cpu_to_le16(0x12), // to be filled
 +};
 +
 +/* GTB descriptor template: most items are replaced dynamically */
 +static struct usb_ms20_gr_trm_block_descriptor gtb_desc = {
 +	.bLength =		sizeof(gtb_desc),
 +	.bDescriptorType =	USB_DT_CS_GR_TRM_BLOCK,
 +	.bDescriptorSubtype =	USB_MS_GR_TRM_BLOCK,
 +	.bGrpTrmBlkID =		0x01,
 +	.bGrpTrmBlkType =	USB_MS_GR_TRM_BLOCK_TYPE_BIDIRECTIONAL,
 +	.nGroupTrm =		0x00,
 +	.nNumGroupTrm =		1,
 +	.iBlockItem =		0,
 +	.bMIDIProtocol =	USB_MS_MIDI_PROTO_1_0_64,
 +	.wMaxInputBandwidth =	0,
 +	.wMaxOutputBandwidth =	0,
 +};
 +
 +DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
 +DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1);
 +DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
 +DECLARE_USB_MS20_ENDPOINT_DESCRIPTOR(32);
 +
 +#define EP_MAX_PACKET_INT	8
 +
 +/* Audio Control Interface */
 +static struct usb_interface_descriptor midi2_audio_if_desc = {
 +	.bLength =		USB_DT_INTERFACE_SIZE,
 +	.bDescriptorType =	USB_DT_INTERFACE,
 +	.bInterfaceNumber =	0, // to be filled
 +	.bNumEndpoints =	0,
 +	.bInterfaceClass =	USB_CLASS_AUDIO,
 +	.bInterfaceSubClass =	USB_SUBCLASS_AUDIOCONTROL,
 +	.bInterfaceProtocol =	0,
 +	.iInterface =		0,
 +};
 +
 +static struct uac1_ac_header_descriptor_1 midi2_audio_class_desc = {
 +	.bLength =		0x09,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	0x01,
 +	.bcdADC =		__cpu_to_le16(0x0100),
 +	.wTotalLength =		__cpu_to_le16(0x0009),
 +	.bInCollection =	0x01,
 +	.baInterfaceNr =	{ 0x01 }, // to be filled
 +};
 +
 +/* MIDI 1.0 Streaming Interface (altset 0) */
 +static struct usb_interface_descriptor midi2_midi1_if_desc = {
 +	.bLength =		USB_DT_INTERFACE_SIZE,
 +	.bDescriptorType =	USB_DT_INTERFACE,
 +	.bInterfaceNumber =	0, // to be filled
 +	.bAlternateSetting =	0,
 +	.bNumEndpoints =	2,
 +	.bInterfaceClass =	USB_CLASS_AUDIO,
 +	.bInterfaceSubClass =	USB_SUBCLASS_MIDISTREAMING,
 +	.bInterfaceProtocol =	0,
 +	.iInterface =		0, // to be filled
 +};
 +
 +static struct usb_ms_header_descriptor midi2_midi1_class_desc = {
 +	.bLength =		0x07,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_HEADER,
 +	.bcdMSC =		__cpu_to_le16(0x0100),
 +	.wTotalLength =		__cpu_to_le16(0x41), // to be calculated
 +};
 +
 +/* MIDI 1.0 IN (Embedded) Jack */
 +static struct usb_midi_in_jack_descriptor midi2_midi1_in_jack1_desc = {
 +	.bLength =		0x06,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_MIDI_IN_JACK,
 +	.bJackType =		USB_MS_EMBEDDED,
 +	.bJackID =		0x01,
 +	.iJack =		0,
 +};
 +
 +/* MIDI 1.0 IN (External) Jack */
 +static struct usb_midi_in_jack_descriptor midi2_midi1_in_jack2_desc = {
 +	.bLength =		0x06,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_MIDI_IN_JACK,
 +	.bJackType =		USB_MS_EXTERNAL,
 +	.bJackID =		0x02,
 +	.iJack =		0,
 +};
 +
 +/* MIDI 1.0 OUT (Embedded) Jack */
 +static struct usb_midi_out_jack_descriptor_1 midi2_midi1_out_jack1_desc = {
 +	.bLength =		0x09,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_MIDI_OUT_JACK,
 +	.bJackType =		USB_MS_EMBEDDED,
 +	.bJackID =		0x03,
 +	.bNrInputPins =		1,
 +	.pins =			{ { 0x02, 0x01 } },
 +	.iJack =		0,
 +};
 +
 +/* MIDI 1.0 OUT (External) Jack */
 +static struct usb_midi_out_jack_descriptor_1 midi2_midi1_out_jack2_desc = {
 +	.bLength =		0x09,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_MIDI_OUT_JACK,
 +	.bJackType =		USB_MS_EXTERNAL,
 +	.bJackID =		0x04,
 +	.bNrInputPins =		1,
 +	.pins =			{ { 0x01, 0x01 } },
 +	.iJack =		0,
 +};
 +
 +/* MIDI 1.0 EP OUT */
 +static struct usb_endpoint_descriptor midi2_midi1_ep_out_desc = {
 +	.bLength =		USB_DT_ENDPOINT_AUDIO_SIZE,
 +	.bDescriptorType =	USB_DT_ENDPOINT,
 +	.bEndpointAddress =	USB_DIR_OUT | 0, // set up dynamically
 +	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
 +};
 +
 +static struct usb_ss_ep_comp_descriptor midi2_midi1_ep_out_ss_comp_desc = {
 +	.bLength                = sizeof(midi2_midi1_ep_out_ss_comp_desc),
 +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
 +};
 +
 +static struct usb_ms_endpoint_descriptor_1 midi2_midi1_ep_out_class_desc = {
 +	.bLength =		0x05,
 +	.bDescriptorType =	USB_DT_CS_ENDPOINT,
 +	.bDescriptorSubtype =	USB_MS_GENERAL,
 +	.bNumEmbMIDIJack =	1,
 +	.baAssocJackID =	{ 0x01 },
 +};
 +
 +/* MIDI 1.0 EP IN */
 +static struct usb_endpoint_descriptor midi2_midi1_ep_in_desc = {
 +	.bLength =		USB_DT_ENDPOINT_AUDIO_SIZE,
 +	.bDescriptorType =	USB_DT_ENDPOINT,
 +	.bEndpointAddress =	USB_DIR_IN | 0, // set up dynamically
 +	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
 +};
 +
 +static struct usb_ss_ep_comp_descriptor midi2_midi1_ep_in_ss_comp_desc = {
 +	.bLength                = sizeof(midi2_midi1_ep_in_ss_comp_desc),
 +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
 +};
 +
 +static struct usb_ms_endpoint_descriptor_1 midi2_midi1_ep_in_class_desc = {
 +	.bLength =		0x05,
 +	.bDescriptorType =	USB_DT_CS_ENDPOINT,
 +	.bDescriptorSubtype =	USB_MS_GENERAL,
 +	.bNumEmbMIDIJack =	1,
 +	.baAssocJackID =	{ 0x03 },
 +};
 +
 +/* MIDI 2.0 Streaming Interface (altset 1) */
 +static struct usb_interface_descriptor midi2_midi2_if_desc = {
 +	.bLength =		USB_DT_INTERFACE_SIZE,
 +	.bDescriptorType =	USB_DT_INTERFACE,
 +	.bInterfaceNumber =	0, // to be filled
 +	.bAlternateSetting =	1,
 +	.bNumEndpoints =	2,
 +	.bInterfaceClass =	USB_CLASS_AUDIO,
 +	.bInterfaceSubClass =	USB_SUBCLASS_MIDISTREAMING,
 +	.bInterfaceProtocol =	0,
 +	.iInterface =		0, // to be filled
 +};
 +
 +static struct usb_ms_header_descriptor midi2_midi2_class_desc = {
 +	.bLength =		0x07,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_HEADER,
 +	.bcdMSC =		__cpu_to_le16(0x0200),
 +	.wTotalLength =		__cpu_to_le16(0x07),
 +};
 +
 +/* MIDI 2.0 EP OUT */
 +static struct usb_endpoint_descriptor midi2_midi2_ep_out_desc[MAX_UMP_EPS];
 +
 +static struct usb_ss_ep_comp_descriptor midi2_midi2_ep_out_ss_comp_desc = {
 +	.bLength                = sizeof(midi2_midi1_ep_out_ss_comp_desc),
 +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
 +};
 +
 +static struct usb_ms20_endpoint_descriptor_32 midi2_midi2_ep_out_class_desc[MAX_UMP_EPS];
 +
 +/* MIDI 2.0 EP IN */
 +static struct usb_endpoint_descriptor midi2_midi2_ep_in_desc[MAX_UMP_EPS];
 +
 +static struct usb_ss_ep_comp_descriptor midi2_midi2_ep_in_ss_comp_desc = {
 +	.bLength                = sizeof(midi2_midi2_ep_in_ss_comp_desc),
 +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
 +};
 +
 +static struct usb_ms20_endpoint_descriptor_32 midi2_midi2_ep_in_class_desc[MAX_UMP_EPS];
 +
 +/* Arrays of descriptors to be created */
 +static void *midi2_audio_descs[] = {
 +	&midi2_audio_if_desc,
 +	&midi2_audio_class_desc,
 +	NULL
 +};
 +
 +static void *midi2_midi1_descs[] = {
 +	&midi2_midi1_if_desc,
 +	&midi2_midi1_class_desc,
 +	&midi2_midi1_in_jack1_desc,
 +	&midi2_midi1_in_jack2_desc,
 +	&midi2_midi1_out_jack1_desc,
 +	&midi2_midi1_out_jack2_desc,
 +	NULL
 +};
 +
 +static void *midi2_midi1_ep_descs[] = {
 +	&midi2_midi1_ep_out_desc,
 +	&midi2_midi1_ep_out_class_desc,
 +	&midi2_midi1_ep_in_desc,
 +	&midi2_midi1_ep_in_class_desc,
 +	NULL
 +};
 +
 +static void *midi2_midi1_ep_ss_descs[] = {
 +	&midi2_midi1_ep_out_desc,
 +	&midi2_midi1_ep_out_ss_comp_desc,
 +	&midi2_midi1_ep_out_class_desc,
 +	&midi2_midi1_ep_in_desc,
 +	&midi2_midi1_ep_in_ss_comp_desc,
 +	&midi2_midi1_ep_in_class_desc,
 +	NULL
 +};
 +
 +static void *midi2_midi2_descs[] = {
 +	&midi2_midi2_if_desc,
 +	&midi2_midi2_class_desc,
 +	NULL
 +};
 +
 +/*
 + * USB request handling
 + */
 +
 +/* get an empty request for the given EP */
 +static struct usb_request *get_empty_request(struct f_midi2_usb_ep *usb_ep)
 +{
 +	struct usb_request *req = NULL;
 +	unsigned long flags;
 +	int index;
 +
 +	spin_lock_irqsave(&usb_ep->card->queue_lock, flags);
 +	if (!usb_ep->free_reqs)
 +		goto unlock;
 +	index = find_first_bit(&usb_ep->free_reqs, usb_ep->num_reqs);
 +	if (index >= usb_ep->num_reqs)
 +		goto unlock;
 +	req = usb_ep->reqs[index].req;
 +	if (!req)
 +		goto unlock;
 +	clear_bit(index, &usb_ep->free_reqs);
 +	req->length = 0;
 + unlock:
 +	spin_unlock_irqrestore(&usb_ep->card->queue_lock, flags);
 +	return req;
 +}
 +
 +/* put the empty request back */
 +static void put_empty_request(struct usb_request *req)
 +{
 +	struct f_midi2_req_ctx *ctx = req->context;
 +	unsigned long flags;
 +
 +	spin_lock_irqsave(&ctx->usb_ep->card->queue_lock, flags);
 +	set_bit(ctx->index, &ctx->usb_ep->free_reqs);
 +	spin_unlock_irqrestore(&ctx->usb_ep->card->queue_lock, flags);
 +}
 +
 +/*
 + * UMP v1.1 Stream message handling
 + */
 +
 +/* queue a request to UMP EP; request is either queued or freed after this */
 +static int queue_request_ep_raw(struct usb_request *req)
 +{
 +	struct f_midi2_req_ctx *ctx = req->context;
 +	int err;
 +
 +	req->complete = ctx->usb_ep->complete;
 +	err = usb_ep_queue(ctx->usb_ep->usb_ep, req, GFP_ATOMIC);
 +	if (err) {
 +		put_empty_request(req);
 +		return err;
 +	}
 +	return 0;
 +}
 +
 +/* queue a request with endianness conversion */
 +static int queue_request_ep_in(struct usb_request *req)
 +{
 +	/* UMP packets have to be converted to little-endian */
 +	cpu_to_le32_array((u32 *)req->buf, req->length >> 2);
 +	return queue_request_ep_raw(req);
 +}
 +
 +/* reply a UMP packet via EP-in */
 +static int reply_ep_in(struct f_midi2_ep *ep, const void *buf, int len)
 +{
 +	struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
 +	struct usb_request *req;
 +
 +	req = get_empty_request(usb_ep);
 +	if (!req)
 +		return -ENOSPC;
 +
 +	req->length = len;
 +	memcpy(req->buf, buf, len);
 +	return queue_request_ep_in(req);
 +}
 +
 +/* reply a UMP stream EP info */
 +static void reply_ump_stream_ep_info(struct f_midi2_ep *ep)
 +{
 +	struct snd_ump_stream_msg_ep_info rep = {
 +		.type = UMP_MSG_TYPE_STREAM,
 +		.status = UMP_STREAM_MSG_STATUS_EP_INFO,
 +		.ump_version_major = 0x01,
 +		.ump_version_minor = 0x01,
 +		.num_function_blocks = ep->num_blks,
 +		.static_function_block = !!ep->card->info.static_block,
 +		.protocol = (UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 |
 +			     UMP_STREAM_MSG_EP_INFO_CAP_MIDI2) >> 8,
 +	};
 +
 +	reply_ep_in(ep, &rep, sizeof(rep));
 +}
 +
 +/* reply a UMP EP device info */
 +static void reply_ump_stream_ep_device(struct f_midi2_ep *ep)
 +{
 +	struct snd_ump_stream_msg_devince_info rep = {
 +		.type = UMP_MSG_TYPE_STREAM,
 +		.status = UMP_STREAM_MSG_STATUS_DEVICE_INFO,
 +		.manufacture_id = ep->info.manufacturer,
 +		.family_lsb = ep->info.family & 0xff,
 +		.family_msb = (ep->info.family >> 8) & 0xff,
 +		.model_lsb = ep->info.model & 0xff,
 +		.model_msb = (ep->info.model >> 8) & 0xff,
 +		.sw_revision = ep->info.sw_revision,
 +	};
 +
 +	reply_ep_in(ep, &rep, sizeof(rep));
 +}
 +
 +#define UMP_STREAM_PKT_BYTES	16	/* UMP stream packet size = 16 bytes*/
 +#define UMP_STREAM_EP_STR_OFF	2	/* offset of name string for EP info */
 +#define UMP_STREAM_FB_STR_OFF	3	/* offset of name string for FB info */
 +
 +/* Helper to replay a string */
 +static void reply_ump_stream_string(struct f_midi2_ep *ep, const u8 *name,
 +				    unsigned int type, unsigned int extra,
 +				    unsigned int start_ofs)
 +{
 +	struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
 +	struct f_midi2 *midi2 = ep->card;
 +	struct usb_request *req;
 +	unsigned int pos;
 +	u32 *buf;
 +
 +	if (!*name)
 +		return;
 +	req = get_empty_request(usb_ep);
 +	if (!req)
 +		return;
 +
 +	buf = (u32 *)req->buf;
 +	pos = start_ofs;
 +	for (;;) {
 +		if (pos == start_ofs) {
 +			memset(buf, 0, UMP_STREAM_PKT_BYTES);
 +			buf[0] = ump_stream_compose(type, 0) | extra;
 +		}
 +		buf[pos / 4] |= *name++ << ((3 - (pos % 4)) * 8);
 +		if (!*name) {
 +			if (req->length)
 +				buf[0] |= UMP_STREAM_MSG_FORMAT_END << 26;
 +			req->length += UMP_STREAM_PKT_BYTES;
 +			break;
 +		}
 +		if (++pos == UMP_STREAM_PKT_BYTES) {
 +			if (!req->length)
 +				buf[0] |= UMP_STREAM_MSG_FORMAT_START << 26;
 +			else
 +				buf[0] |= UMP_STREAM_MSG_FORMAT_CONTINUE << 26;
 +			req->length += UMP_STREAM_PKT_BYTES;
 +			if (midi2->info.req_buf_size - req->length < UMP_STREAM_PKT_BYTES)
 +				break;
 +			buf += 4;
 +			pos = start_ofs;
 +		}
 +	}
 +
 +	if (req->length)
 +		queue_request_ep_in(req);
 +	else
 +		put_empty_request(req);
 +}
 +
 +/* Reply a UMP EP name string */
 +static void reply_ump_stream_ep_name(struct f_midi2_ep *ep)
 +{
 +	reply_ump_stream_string(ep, ump_ep_name(ep),
 +				UMP_STREAM_MSG_STATUS_EP_NAME, 0,
 +				UMP_STREAM_EP_STR_OFF);
 +}
 +
 +/* Reply a UMP EP product ID string */
 +static void reply_ump_stream_ep_pid(struct f_midi2_ep *ep)
 +{
 +	reply_ump_stream_string(ep, ump_product_id(ep),
 +				UMP_STREAM_MSG_STATUS_PRODUCT_ID, 0,
 +				UMP_STREAM_EP_STR_OFF);
 +}
 +
 +/* Reply a UMP EP stream config */
 +static void reply_ump_stream_ep_config(struct f_midi2_ep *ep)
 +{
 +	struct snd_ump_stream_msg_stream_cfg rep = {
 +		.type = UMP_MSG_TYPE_STREAM,
 +		.status = UMP_STREAM_MSG_STATUS_STREAM_CFG,
 +	};
 +
 +	if ((ep->info.protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK) ==
 +	    SNDRV_UMP_EP_INFO_PROTO_MIDI2)
 +		rep.protocol = UMP_STREAM_MSG_EP_INFO_CAP_MIDI2 >> 8;
 +	else
 +		rep.protocol = UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 >> 8;
 +
 +	reply_ep_in(ep, &rep, sizeof(rep));
 +}
 +
 +/* Reply a UMP FB info */
 +static void reply_ump_stream_fb_info(struct f_midi2_ep *ep, int blk)
 +{
 +	struct f_midi2_block_info *b = &ep->blks[blk].info;
 +	struct snd_ump_stream_msg_fb_info rep = {
 +		.type = UMP_MSG_TYPE_STREAM,
 +		.status = UMP_STREAM_MSG_STATUS_FB_INFO,
 +		.active = !!b->active,
 +		.function_block_id = blk,
 +		.ui_hint = b->ui_hint,
 +		.midi_10 = b->is_midi1,
 +		.direction = b->direction,
 +		.first_group = b->first_group,
 +		.num_groups = b->num_groups,
 +		.midi_ci_version = b->midi_ci_version,
 +		.sysex8_streams = b->sysex8_streams,
 +	};
 +
 +	reply_ep_in(ep, &rep, sizeof(rep));
 +}
 +
 +/* Reply a FB name string */
 +static void reply_ump_stream_fb_name(struct f_midi2_ep *ep, unsigned int blk)
 +{
 +	reply_ump_stream_string(ep, ump_fb_name(&ep->blks[blk].info),
 +				UMP_STREAM_MSG_STATUS_FB_NAME, blk << 8,
 +				UMP_STREAM_FB_STR_OFF);
 +}
 +
 +/* Process a UMP Stream message */
 +static void process_ump_stream_msg(struct f_midi2_ep *ep, const u32 *data)
 +{
 +	struct f_midi2 *midi2 = ep->card;
 +	unsigned int format, status, blk;
 +
 +	format = ump_stream_message_format(*data);
 +	status = ump_stream_message_status(*data);
 +	switch (status) {
 +	case UMP_STREAM_MSG_STATUS_EP_DISCOVERY:
 +		if (format)
 +			return; // invalid
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_EP_INFO)
 +			reply_ump_stream_ep_info(ep);
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_DEVICE_INFO)
 +			reply_ump_stream_ep_device(ep);
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_EP_NAME)
 +			reply_ump_stream_ep_name(ep);
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_PRODUCT_ID)
 +			reply_ump_stream_ep_pid(ep);
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_STREAM_CFG)
 +			reply_ump_stream_ep_config(ep);
 +		return;
 +	case UMP_STREAM_MSG_STATUS_STREAM_CFG_REQUEST:
 +		if (*data & UMP_STREAM_MSG_EP_INFO_CAP_MIDI2) {
 +			ep->info.protocol = SNDRV_UMP_EP_INFO_PROTO_MIDI2;
 +			DBG(midi2, "Switching Protocol to MIDI2\n");
 +		} else {
 +			ep->info.protocol = SNDRV_UMP_EP_INFO_PROTO_MIDI1;
 +			DBG(midi2, "Switching Protocol to MIDI1\n");
 +		}
 +		snd_ump_switch_protocol(ep->ump, ep->info.protocol);
 +		reply_ump_stream_ep_config(ep);
 +		return;
 +	case UMP_STREAM_MSG_STATUS_FB_DISCOVERY:
 +		if (format)
 +			return; // invalid
 +		blk = (*data >> 8) & 0xff;
 +		if (blk >= ep->num_blks)
 +			return;
 +		if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO)
 +			reply_ump_stream_fb_info(ep, blk);
 +		if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME)
 +			reply_ump_stream_fb_name(ep, blk);
 +		return;
 +	}
 +}
 +
 +/* Process UMP messages included in a USB request */
 +static void process_ump(struct f_midi2_ep *ep, const struct usb_request *req)
 +{
 +	const u32 *data = (u32 *)req->buf;
 +	int len = req->actual >> 2;
 +	const u32 *in_buf = ep->ump->input_buf;
 +
 +	for (; len > 0; len--, data++) {
 +		if (snd_ump_receive_ump_val(ep->ump, *data) <= 0)
 +			continue;
 +		if (ump_message_type(*in_buf) == UMP_MSG_TYPE_STREAM)
 +			process_ump_stream_msg(ep, in_buf);
 +	}
 +}
 +
 +/*
 + * MIDI 2.0 UMP USB request handling
 + */
 +
 +/* complete handler for UMP EP-out requests */
 +static void f_midi2_ep_out_complete(struct usb_ep *usb_ep,
 +				    struct usb_request *req)
 +{
 +	struct f_midi2_req_ctx *ctx = req->context;
 +	struct f_midi2_ep *ep = ctx->usb_ep->ep;
 +	struct f_midi2 *midi2 = ep->card;
 +	int status = req->status;
 +
 +	if (status) {
 +		DBG(midi2, "%s complete error %d: %d/%d\n",
 +		    usb_ep->name, status, req->actual, req->length);
 +		goto error;
 +	}
 +
 +	/* convert to UMP packet in native endianness */
 +	le32_to_cpu_array((u32 *)req->buf, req->actual >> 2);
 +
 +	if (midi2->info.process_ump)
 +		process_ump(ep, req);
 +
 +	snd_ump_receive(ep->ump, req->buf, req->actual & ~3);
 +
 +	if (midi2->operation_mode != MIDI_OP_MODE_MIDI2)
 +		goto error;
 +
 +	if (queue_request_ep_raw(req))
 +		goto error;
 +	return;
 +
 + error:
 +	put_empty_request(req);
 +}
 +
 +/* Transmit UMP packets received from user-space to the gadget */
 +static void process_ump_transmit(struct f_midi2_ep *ep)
 +{
 +	struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
 +	struct f_midi2 *midi2 = ep->card;
 +	struct usb_request *req;
 +	int len;
 +
 +	if (!usb_ep->usb_ep->enabled)
 +		return;
 +
 +	for (;;) {
 +		req = get_empty_request(usb_ep);
 +		if (!req)
 +			break;
 +		len = snd_ump_transmit(ep->ump, (u32 *)req->buf,
 +				       midi2->info.req_buf_size);
 +		if (len <= 0) {
 +			put_empty_request(req);
 +			break;
 +		}
 +
 +		req->length = len;
 +		if (queue_request_ep_in(req) < 0)
 +			break;
 +	}
 +}
 +
 +/* Complete handler for UMP EP-in requests */
 +static void f_midi2_ep_in_complete(struct usb_ep *usb_ep,
 +				   struct usb_request *req)
 +{
 +	struct f_midi2_req_ctx *ctx = req->context;
 +	struct f_midi2_ep *ep = ctx->usb_ep->ep;
 +	struct f_midi2 *midi2 = ep->card;
 +	int status = req->status;
 +
 +	put_empty_request(req);
 +
 +	if (status) {
 +		DBG(midi2, "%s complete error %d: %d/%d\n",
 +		    usb_ep->name, status, req->actual, req->length);
 +		return;
 +	}
 +
 +	process_ump_transmit(ep);
 +}
 +
 +/* Start MIDI EP */
 +static int f_midi2_start_ep(struct f_midi2_usb_ep *usb_ep,
 +			    struct usb_function *fn)
 +{
 +	int err;
 +
 +	usb_ep_disable(usb_ep->usb_ep);
 +	err = config_ep_by_speed(usb_ep->card->gadget, fn, usb_ep->usb_ep);
 +	if (err)
 +		return err;
 +	return usb_ep_enable(usb_ep->usb_ep);
 +}
 +
 +/* Drop pending requests */
 +static void f_midi2_drop_reqs(struct f_midi2_usb_ep *usb_ep)
 +{
 +	int i;
 +
 +	if (!usb_ep->num_reqs)
 +		return;
 +
 +	for (i = 0; i < usb_ep->num_reqs; i++) {
 +		if (!test_bit(i, &usb_ep->free_reqs) && usb_ep->reqs[i].req) {
 +			usb_ep_dequeue(usb_ep->usb_ep, usb_ep->reqs[i].req);
 +			set_bit(i, &usb_ep->free_reqs);
 +		}
 +	}
 +}
 +
 +/* Allocate requests for the given EP */
 +static int f_midi2_alloc_ep_reqs(struct f_midi2_usb_ep *usb_ep)
 +{
 +	struct f_midi2 *midi2 = usb_ep->card;
 +	int i;
 +
 +	if (!usb_ep->reqs)
 +		return -EINVAL;
 +
 +	for (i = 0; i < midi2->info.num_reqs; i++) {
 +		if (usb_ep->reqs[i].req)
 +			continue;
 +		usb_ep->reqs[i].req = alloc_ep_req(usb_ep->usb_ep,
 +						   midi2->info.req_buf_size);
 +		if (!usb_ep->reqs[i].req)
 +			return -ENOMEM;
 +		usb_ep->reqs[i].req->context = &usb_ep->reqs[i];
 +	}
 +	return 0;
 +}
 +
 +/* Free allocated requests */
 +static void f_midi2_free_ep_reqs(struct f_midi2_usb_ep *usb_ep)
 +{
 +	struct f_midi2 *midi2 = usb_ep->card;
 +	int i;
 +
 +	for (i = 0; i < midi2->info.num_reqs; i++) {
 +		if (!usb_ep->reqs[i].req)
 +			continue;
 +		free_ep_req(usb_ep->usb_ep, usb_ep->reqs[i].req);
 +		usb_ep->reqs[i].req = NULL;
 +	}
 +}
 +
 +/* Initialize EP */
 +static int f_midi2_init_ep(struct f_midi2 *midi2, struct f_midi2_ep *ep,
 +			   struct f_midi2_usb_ep *usb_ep,
 +			   void *desc, int num_reqs,
 +			   void (*complete)(struct usb_ep *usb_ep,
 +					    struct usb_request *req))
 +{
 +	int i;
 +
 +	usb_ep->card = midi2;
 +	usb_ep->ep = ep;
 +	usb_ep->usb_ep = usb_ep_autoconfig(midi2->gadget, desc);
 +	if (!usb_ep->usb_ep)
 +		return -ENODEV;
 +	usb_ep->complete = complete;
 +
 +	if (num_reqs) {
 +		usb_ep->reqs = kcalloc(num_reqs, sizeof(*usb_ep->reqs),
 +				       GFP_KERNEL);
 +		if (!usb_ep->reqs)
 +			return -ENOMEM;
 +		for (i = 0; i < num_reqs; i++) {
 +			usb_ep->reqs[i].index = i;
 +			usb_ep->reqs[i].usb_ep = usb_ep;
 +			set_bit(i, &usb_ep->free_reqs);
 +			usb_ep->num_reqs++;
 +		}
 +	}
 +
 +	return 0;
 +}
 +
 +/* Free EP */
 +static void f_midi2_free_ep(struct f_midi2_usb_ep *usb_ep)
 +{
 +	f_midi2_drop_reqs(usb_ep);
 +
 +	f_midi2_free_ep_reqs(usb_ep);
 +
 +	kfree(usb_ep->reqs);
 +	usb_ep->num_reqs = 0;
 +	usb_ep->free_reqs = 0;
 +	usb_ep->reqs = NULL;
 +}
 +
 +/* Queue requests for EP-out at start */
 +static void f_midi2_queue_out_reqs(struct f_midi2_usb_ep *usb_ep)
 +{
 +	int i, err;
 +
 +	for (i = 0; i < usb_ep->num_reqs; i++) {
 +		if (!test_bit(i, &usb_ep->free_reqs) || !usb_ep->reqs[i].req)
 +			continue;
 +		usb_ep->reqs[i].req->complete = usb_ep->complete;
 +		err = usb_ep_queue(usb_ep->usb_ep, usb_ep->reqs[i].req,
 +				   GFP_ATOMIC);
 +		if (!err)
 +			clear_bit(i, &usb_ep->free_reqs);
 +	}
 +}
 +
 +/*
 + * Gadget Function callbacks
 + */
 +
 +/* gadget function set_alt callback */
 +static int f_midi2_set_alt(struct usb_function *fn, unsigned int intf,
 +			   unsigned int alt)
 +{
 +	struct f_midi2 *midi2 = func_to_midi2(fn);
 +	struct f_midi2_ep *ep;
 +	int i, op_mode, err;
 +
 +	if (intf != midi2->midi_if || alt > 1)
 +		return 0;
 +
 +	if (alt == 0)
 +		op_mode = MIDI_OP_MODE_MIDI1;
 +	else if (alt == 1)
 +		op_mode = MIDI_OP_MODE_MIDI2;
 +	else
 +		op_mode = MIDI_OP_MODE_UNSET;
 +
 +	if (midi2->operation_mode == op_mode)
 +		return 0;
 +
]
]

368/2 2026/07/30 15:09 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 20311
							output: 43
							thoughts: 99
						

Thoughts:
**Analyzing Potential Memory Leaks in MIDI Driver Code**

Okay, so commit `8b645922b22303cec4628dbbbf6c8553d1cdec87` seems interesting. It looks like it introduced `f_midi2_free_inst` and `f_midi2_ep_opts_release`, which is probably related to cleaning up MIDI 2.0 instances. My initial thought is to zero in on `f_midi2_free_inst` and check for potential memory leaks, specifically around the `configfs` interaction. We all know how easy it is to miss a `configfs_remove_default_groups` call, and if that's the case we could have a nasty memory leak. I'll need to dive into the source code of that function within this commit and look for any clues. Let's see what's what...



369/2 2026/07/30 15:09 tool grepper
0m Args:
map[Expression:f_midi2_free_inst PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:drivers/usb/gadget/function/f_midi2.c=2629=static const struct config_item_type f_midi2_func_type = {
--
drivers/usb/gadget/function/f_midi2.c-2635-
drivers/usb/gadget/function/f_midi2.c:2636:static void f_midi2_free_inst(struct usb_function_instance *f)
drivers/usb/gadget/function/f_midi2.c-2637-{
--
drivers/usb/gadget/function/f_midi2.c=2647=static struct usb_function_instance *f_midi2_alloc_inst(void)
--
drivers/usb/gadget/function/f_midi2.c-2658-	mutex_init(&opts->lock);
drivers/usb/gadget/function/f_midi2.c:2659:	opts->func_inst.free_func_inst = f_midi2_free_inst;
drivers/usb/gadget/function/f_midi2.c-2660-	opts->info.process_ump = true;
]

370/2 2026/07/30 15:09 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 20946
							output: 48
							thoughts: 43
						

Thoughts:
Here's my analysis of the provided information, as if these were my own thoughts:

**Dissecting `f_midi2_free_inst` Implementation**

Okay, so I need to dive into the `f_midi2_free_inst` function. The context suggests it's within the `f_midi2.c` file, specifically within the USB gadget driver code, and I'm guessing around line 2636. I want to see how this function handles deallocation of a MIDI 2.0 instance. I need to understand what resources it's freeing and in what order. I'm assuming it handles device removal or disconnection. I'm looking for memory leaks, improper locking (especially with those USB gadget drivers - you gotta be careful), or any potential race conditions. I need to verify that it's gracefully shutting down all the associated endpoints and releasing any device-specific data structures. My focus is on resource management. I'll check to see if it frees the `midi2_inst` struct and any associated buffer allocated memory. It's also important to check it handles any potential errors.



371/2 2026/07/30 15:09 tool read-file
0m Error:
argument "FirstLine" has wrong type: got string, want int

Args:
map[File:drivers/usb/gadget/function/f_midi2.c FirstLine:2636 LineCount:20]

372/2 2026/07/30 15:09 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 21303
							output: 44
							thoughts: 11
						

Thoughts:
Okay, here's the summary, rendered as your internal thought process:

**Integer Data Type Verification**

Alright, let's take a look at this. Immediately, my initial assessment of the data type associated with `FirstLine` is, it is critical that this is an integer. Ensuring that this variable is defined and utilized with proper type is essential for computation and subsequent analysis. I can now begin verifying if the current instantiation and all subsequent operations, throughout the program, will be handled correctly with the assigned datatype. The value of `FirstLine` must be rigorously checked and compared.



373/2 2026/07/30 15:09 tool read-file
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c FirstLine:2636 LineCount:20]

Results:
map[Contents:2636:	static void f_midi2_free_inst(struct usb_function_instance *f)
2637:	{
2638:		struct f_midi2_opts *opts;
2639:	
2640:		opts = container_of(f, struct f_midi2_opts, func_inst);
2641:	
2642:		kfree(opts->info.iface_name);
2643:		kfree(opts);
2644:	}
2645:	
2646:	/* gadget alloc_inst */
2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
2655:		if (!opts)
]

374/2 2026/07/30 15:09 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 21781
							output: 45
							thoughts: 42
						

Thoughts:
Okay, here's my interpretation of those thoughts, summarized from my perspective as an expert in the field:

**Digging into the MIDI Function Driver**

Alright, so `f_midi2_free_inst` *doesn't* contain the `configfs_remove_default_groups` function, which is interesting. Given that we're talking about resource cleanup, that's a key omission to be aware of. Let's shift our focus and investigate `f_midi2_ep_opts_release` instead. It seems that might be where we'll find the removal/cleanup logic that's missing from the previous function. I'll need to see how the endpoint options are released and whether the default groups are handled there.



375/2 2026/07/30 15:10 tool grepper
0m Args:
map[Expression:f_midi2_ep_opts_release PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:drivers/usb/gadget/function/f_midi2.c=2460=static struct configfs_attribute *f_midi2_ep_attrs[] = {
--
drivers/usb/gadget/function/f_midi2.c-2471-
drivers/usb/gadget/function/f_midi2.c:2472:static void f_midi2_ep_opts_release(struct config_item *item)
drivers/usb/gadget/function/f_midi2.c-2473-{
--
drivers/usb/gadget/function/f_midi2.c=2481=static const struct configfs_item_operations f_midi2_ep_item_ops = {
drivers/usb/gadget/function/f_midi2.c:2482:	.release	= f_midi2_ep_opts_release,
drivers/usb/gadget/function/f_midi2.c-2483-};
]

376/2 2026/07/30 15:10 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 22272
							output: 44
							thoughts: 16
						

Thoughts:
Okay, let's dive into this. Here's my thought process as I approach reading this:

**Analyzing `f_midi2_ep_opts_release`**

Alright, I'm starting with `f_midi2_ep_opts_release`. Immediately, I'm thinking: this function name is pretty descriptive, which is a good sign. The `f_` prefix likely indicates it's a function. `midi2` suggests this deals with MIDI 2.0, which is important to know contextually – it's going to be a different paradigm than older MIDI implementations. The `ep` part… that's got me guessing. Could be endpoint, or maybe even event processing. Then, the `opts_release` part... Options are being released? That could imply freeing memory associated with some option settings, or possibly releasing a lock or resource related to those options.

So, overall, my initial mental model is that this function likely pertains to releasing resources or configurations tied to MIDI 2.0 endpoint options. The devil, as always, will be in the details. I'm expecting to see some memory deallocation, perhaps some synchronization primitives being manipulated, or possibly even the handling of specific MIDI 2.0-related data structures. I'll be looking for potential error conditions and how they're handled – a well-written release function would be defensive and robust. Let's dig in and see if my hypotheses hold true.



377/2 2026/07/30 15:10 tool read-file
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c FirstLine:2472 LineCount:15]

Results:
map[Contents:2472:	static void f_midi2_ep_opts_release(struct config_item *item)
2473:	{
2474:		struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
2475:	
2476:		kfree(opts->info.ep_name);
2477:		kfree(opts->info.product_id);
2478:		kfree(opts);
2479:	}
2480:	
2481:	static const struct configfs_item_operations f_midi2_ep_item_ops = {
2482:		.release	= f_midi2_ep_opts_release,
2483:	};
2484:	
2485:	static const struct configfs_group_operations f_midi2_ep_group_ops = {
2486:		.make_group	= f_midi2_opts_block_make,
]

378/2 2026/07/30 15:10 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 22906
							output: 44
							thoughts: 221
						

Thoughts:
**Debugging the MIDI2 Gadget Driver Release**

Okay, so I've pinpointed that `f_midi2_ep_opts_release` is also overlooking the removal of `configfs_remove_default_groups`. That's a classic oversight. Now, I recall the introduction of these functions. Looking back at commit `8b645922b22303cec4628dbbbf6c8553d1cdec87`, that's the one. It brought in both the functions *and* this bug, seems like.

Wait, before I go any further, I need to verify something. Was `configfs_remove_default_groups` originally part of this commit, or was it added later and subsequently removed? Let me double-check the history. Right, the commit `8b645922b22303cec4628dbbbf6c8553d1cdec87` is indeed where the `drivers/usb/gadget/function/f_midi2.c` file was added.

Now I need to re-evaluate what's happening. I should double check if the `f_midi2_alloc_inst` function in `8b645922b22303cec4628dbbbf6c8553d1cdec87` actually *adds* the default groups. Once I have established this, I will be able to form a robust plan for remediation.



379/2 2026/07/30 15:10 tool read-file
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c FirstLine:2647 LineCount:40]

Results:
map[Contents:2647:	static struct usb_function_instance *f_midi2_alloc_inst(void)
2648:	{
2649:		struct f_midi2_opts *opts;
2650:		struct f_midi2_ep_opts *ep_opts;
2651:		struct f_midi2_block_opts *block_opts;
2652:		int ret;
2653:	
2654:		opts = kzalloc_obj(*opts);
2655:		if (!opts)
2656:			return ERR_PTR(-ENOMEM);
2657:	
2658:		mutex_init(&opts->lock);
2659:		opts->func_inst.free_func_inst = f_midi2_free_inst;
2660:		opts->info.process_ump = true;
2661:		opts->info.static_block = true;
2662:		opts->info.num_reqs = 32;
2663:		opts->info.req_buf_size = 512;
2664:	
2665:		/* create the default ep */
2666:		ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
2667:		if (ret) {
2668:			kfree(opts);
2669:			return ERR_PTR(ret);
2670:		}
2671:	
2672:		/* create the default block */
2673:		ret = f_midi2_block_opts_create(ep_opts, 0, &block_opts);
2674:		if (ret) {
2675:			kfree(ep_opts);
2676:			kfree(opts);
2677:			return ERR_PTR(ret);
2678:		}
2679:	
2680:		/* set up the default MIDI1 (that is mandatory) */
2681:		block_opts->info.midi1_num_groups = 1;
2682:	
2683:		config_group_init_type_name(&opts->func_inst.group, "",
2684:					    &f_midi2_func_type);
2685:	
2686:		config_group_init_type_name(&ep_opts->group, "ep.0",
]

380/2 2026/07/30 15:10 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 24141
							output: 44
							thoughts: 18
						

Thoughts:
Okay, here's my attempt at summarizing the thought process, as if I were having these thoughts myself, and tailored for an expert audience.

**Diving Back into `f_midi2_alloc_inst`**

Alright, let's take another look at `f_midi2_alloc_inst`. I'm going to re-familiarize myself with its specifics. This is likely related to instrument allocation within the MIDI 2.0 framework, which always presents interesting challenges in terms of resource management and potential concurrency issues. I need to refresh my understanding of how the code handles memory, particularly when creating or releasing instrument instances. I'm focusing on that function specifically, because it's a critical point for understanding how new instances are being managed, which is fundamental to how this framework scales. I'm going to pay extra close attention to how it handles potential allocation failures, and how it deals with the initialization of the underlying instrument structures. I'll be looking for possible bottlenecks or any areas where optimizations might be applicable. Understanding this allocation process is a key element, and will help me be more proficient.



381/2 2026/07/30 15:10 tool read-file
0m Args:
map[File:drivers/usb/gadget/function/f_midi2.c FirstLine:2680 LineCount:20]

Results:
map[Contents:2680:		/* set up the default MIDI1 (that is mandatory) */
2681:		block_opts->info.midi1_num_groups = 1;
2682:	
2683:		config_group_init_type_name(&opts->func_inst.group, "",
2684:					    &f_midi2_func_type);
2685:	
2686:		config_group_init_type_name(&ep_opts->group, "ep.0",
2687:					    &f_midi2_ep_type);
2688:		configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
2689:	
2690:		config_group_init_type_name(&block_opts->group, "block.0",
2691:					    &f_midi2_block_type);
2692:		configfs_add_default_group(&block_opts->group, &ep_opts->group);
2693:	
2694:		return &opts->func_inst;
2695:	}
2696:	
2697:	static void do_f_midi2_free(struct f_midi2 *midi2, struct f_midi2_opts *opts)
2698:	{
2699:		mutex_lock(&opts->lock);
]

382/2 2026/07/30 15:10 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 24804
							output: 31
							thoughts: 141
						

Thoughts:
**Analyzing a Recent Regression**

Okay, so I've traced down a potential regression. It looks like `configfs_add_default_group` *is* indeed called within `f_midi2_alloc_inst` for `ep.0` and `block.0`, which is as expected. What's concerning, however, is that `f_midi2_free_inst` and `f_midi2_ep_opts_release` *don't* seem to have the corresponding `configfs_remove_default_groups` calls. This is a classic leak scenario.

Given this discrepancy, my gut tells me the bug was likely introduced with that specific commit: `8b645922b22303cec4628dbbbf6c8553d1cdec87`. Time to investigate further and confirm this.

But before I jump to conclusions, I need to be thorough. I'll quickly check if any other commits in this file might have inadvertently introduced similar issues around resource management. A broader look might reveal related, overlooked problems. Let's dig in a bit more.



383/2 2026/07/30 15:10 tool git-log
0m Args:
map[PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:224fb8661f66 usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
189f164e573e Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
32a92f8c8932 Convert more 'alloc_obj' cases to default GFP_KERNEL arguments
bf4afc53b77a Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
69050f8d6d07 treewide: Replace kmalloc with kmalloc_obj for non-scalar types
e715bc42e337 usb: gadget: Constify struct configfs_item_operations and configfs_group_operations
116e79c679a1 usb: gadget: midi2: Fix MIDI2 IN EP max packet size
21d8525d2e06 usb: gadget: midi2: Fix missing UMP group attributes initialization
dd33993a9721 ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info
82937056967d usb: gadget: midi2: Fix interpretation of is_midi1 bits
]

384/2 2026/07/30 15:10 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 25522
							output: 36
							thoughts: 157
						

Thoughts:
**Investigating the Missing Commit**

Okay, so I'm looking into this code and I've identified `8b645922b22303cec4628dbbbf6c8553d1cdec87` as the commit that introduced `drivers/usb/gadget/function/f_midi2.c`. But hold on, the output I just got from `git-log` doesn't seem to include that specific SHA. That's odd, and it warrants a closer look.

Let me quickly verify that `8b645922b22303cec4628dbbbf6c8553d1cdec87` is indeed present in the history. It's possible I've misinterpreted something, or that there's a filtering issue somewhere. I'll need to confirm its existence before I can move forward with the analysis. Let's see if it's there.



385/2 2026/07/30 15:10 tool git-log
0m Args:
map[Count:20 PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:224fb8661f66 usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
189f164e573e Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
32a92f8c8932 Convert more 'alloc_obj' cases to default GFP_KERNEL arguments
bf4afc53b77a Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
69050f8d6d07 treewide: Replace kmalloc with kmalloc_obj for non-scalar types
e715bc42e337 usb: gadget: Constify struct configfs_item_operations and configfs_group_operations
116e79c679a1 usb: gadget: midi2: Fix MIDI2 IN EP max packet size
21d8525d2e06 usb: gadget: midi2: Fix missing UMP group attributes initialization
dd33993a9721 ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info
82937056967d usb: gadget: midi2: Fix interpretation of is_midi1 bits
7f72d17359e5 usb: gadget: function: remove redundant else statement
d9c61bb33fbb usb: gadget: function: move u_f.h to include/linux/usb/func_utils.h
228a953e61d6 usb: gadget: midi2: Fix the response for FB info with block 0xff
3eb27d3e32c7 usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
1cb9ba5e61e8 usb: gadget: add missing MODULE_DESCRIPTION() macros
46decc82ffd5 usb: gadget: unconditionally allocate hs/ss descriptor in bind operation
6bb75eb9ff3a usb: gadget: midi2: fix missing unlock in f_midi2_block_opts_create()
a85ff0db48c3 usb: gadget: midi2: More flexible MIDI 1.0 configuration
1b437d2fb3c1 usb: gadget: midi2: Add "Operation Mode" control
d6468be779af usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
]

386/2 2026/07/30 15:10 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 26504
							output: 36
							thoughts: 7
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person:

**Prioritizing Velocity in Development**

Alright, that's a quick thought, and it's telling me to refocus on **increasing our commit frequency**. This isn't just about raw number of commits, of course. For someone in my position, "more commits" translates into a more nuanced set of considerations. It suggests we might be able to improve our:

*   **Iteration speed:** Are we working in too-large batches? Do we need to break down tasks into smaller, more manageable units to demonstrate consistent progress and facilitate faster feedback cycles?
*   **Code Review Efficiency:** A higher commit rate can also facilitate more focused code reviews. Small, self-contained changes are easier to understand and approve. Large pull requests, in comparison, can stagnate for longer periods of time.
*   **Risk Mitigation:** Frequent commits serve as smaller, safer checkpoints. If there's a problem, we can identify when that problem was introduced more readily, allowing for easier rollbacks or debugging.
*   **Collaboration and Visibility:** More commits can translate into greater transparency about project progress and active engagement with the codebase. They also contribute to more granular history, which can be useful for debugging and tracing changes.
*   **Team Dynamics:** A focus on a higher commit frequency could also be meant to improve the team's sense of momentum. If we aren't seeing frequent code merges, it is easy to assume that progress isn't happening. I should consider how my team is seeing our progress.

Ultimately, I need to interpret this directive based on the current context. It's not about arbitrary metrics. It's about optimizing our workflow to accelerate development without sacrificing quality or introducing unnecessary overhead. So, my action plan is to identify bottlenecks, improve iteration size, and consider if my team is on pace.



387/2 2026/07/30 15:10 tool git-log
0m Args:
map[Count:50 PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:224fb8661f66 usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
189f164e573e Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
32a92f8c8932 Convert more 'alloc_obj' cases to default GFP_KERNEL arguments
bf4afc53b77a Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
69050f8d6d07 treewide: Replace kmalloc with kmalloc_obj for non-scalar types
e715bc42e337 usb: gadget: Constify struct configfs_item_operations and configfs_group_operations
116e79c679a1 usb: gadget: midi2: Fix MIDI2 IN EP max packet size
21d8525d2e06 usb: gadget: midi2: Fix missing UMP group attributes initialization
dd33993a9721 ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info
82937056967d usb: gadget: midi2: Fix interpretation of is_midi1 bits
7f72d17359e5 usb: gadget: function: remove redundant else statement
d9c61bb33fbb usb: gadget: function: move u_f.h to include/linux/usb/func_utils.h
228a953e61d6 usb: gadget: midi2: Fix the response for FB info with block 0xff
3eb27d3e32c7 usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
1cb9ba5e61e8 usb: gadget: add missing MODULE_DESCRIPTION() macros
46decc82ffd5 usb: gadget: unconditionally allocate hs/ss descriptor in bind operation
6bb75eb9ff3a usb: gadget: midi2: fix missing unlock in f_midi2_block_opts_create()
a85ff0db48c3 usb: gadget: midi2: More flexible MIDI 1.0 configuration
1b437d2fb3c1 usb: gadget: midi2: Add "Operation Mode" control
d6468be779af usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
856fa444b098 usb: gadget: midi2: Dynamically create MIDI 1.0 altset descriptors
29ee7a4dddd5 usb: gadget: midi2: Add configfs support
8b645922b223 usb: gadget: Add support for USB MIDI 2.0 function driver
]

388/2 2026/07/30 15:10 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 27601
							output: 24
							thoughts: 49
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Investigating the MIDI Gadget ConfigFS Implementation**

Right, so that commit ID, `29ee7a4dddd5`, immediately rings a bell. *That* was the one that brought in ConfigFS support for the USB MIDI gadget. I need to refresh my memory on the details of that implementation. Let's pull up that specific commit and dissect it. I want to see how they structured the ConfigFS interface, what parameters are exposed, and, most importantly, if the design aligns with best practices and considerations for robustness and flexibility. Were the right error checks included? Does it play nice with other gadget configurations? Time to dive in.



389/2 2026/07/30 15:10 tool git-show
0m Args:
map[Commit:29ee7a4dddd5]

Results:
map[Output:commit 29ee7a4dddd5caa18d1cef000f20c6af43f762f1
Author: Takashi Iwai <tiwai@suse.de>
Date:   Tue Jul 25 08:22:01 2023 +0200

    usb: gadget: midi2: Add configfs support
    
    This patch adds the support of configfs to MIDI 2.0 function driver
    for users to allow configuring the UMP Endpoint and Function Blocks
    more flexibly.  The configuration is in a tree form.  The top-most
    contains some card-level configurations.  UMP Endpoints are defined in
    subdirectories (ep.0, ep.1, etc) that contain Endpoint-specific
    configurations such as ep_name, etc.  And, UMP Function Blocks are
    defined in the subdirectories (block.0, block.1, etc) under EP
    subdirectory.  As default, the driver creates a single UMP Endpoint
    (ep.0) and a single Function Block (block.0) to work in a minimalistic
    manner.  User can modify those attributes freely to fit with the
    demands.
    
    When multiple Function Blocks are required, user can create another
    directory as block.1, block.2, and so on (up to block.31).  A block.*
    directory can be deleted dynamically, too.  A caveat is that the block
    number has to be continuous.
    
    Similarly, when multiple UMP Endpoints are required, user can create
    another directory as ep.1, ep.2, up to ep.3.
    
    Also, some driver behavior can be controlled in the card top-level
    configs.  e.g. you can pass process_ump=0 to disable the processing of
    UMP Stream messages.  This would be equivalent with the older MIDI 2.0
    spec that doesn't support UMP v1.1 features.
    
    The configfs interface checks upper- / lower-bound of input values,
    and more sanity checks are performed at binding.
    
    Attributes can't be changed any longer once when the instance is
    linked to UDC.
    
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Link: https://lore.kernel.org/r/20230725062206.9674-3-tiwai@suse.de
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-midi2 b/Documentation/ABI/testing/configfs-usb-gadget-midi2
new file mode 100644
index 000000000000..a3a036d784c7
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-usb-gadget-midi2
@@ -0,0 +1,52 @@
+What:		/config/usb-gadget/gadget/functions/midi2.name
+Date:		Jul 2023
+KernelVersion:	6.6
+Description:
+		The attributes:
+
+		============	===============================================
+		process_ump	Flag to process UMP Stream messages (0 or 1)
+		static_block	Flag for static blocks (0 or 1)
+		iface_name	MIDI interface name string
+		============	===============================================
+
+What:		/config/usb-gadget/gadget/functions/midi2.name/ep.number
+Date:		Jul 2023
+KernelVersion:	6.6
+Description:
+		This group contains a UMP Endpoint configuration.
+		A new Endpoint starts from 0, and can be up to 3.
+
+		The attributes:
+
+		=============	===============================================
+		protocol_caps	MIDI protocol capabilities (1, 2 or 3 for both)
+		protocol	Default MIDI protocol (1 or 2)
+		ep_name		UMP Endpoint name string
+		product_id	Product ID string
+		manufacturer	Manufacture ID (24 bit)
+		family		Device family ID (16 bit)
+		model		Device model ID (16 bit)
+		sw_revision	Software Revision (32 bit)
+		=============	===============================================
+
+What:		/config/usb-gadget/gadget/functions/midi2.name/ep.number/block.number
+Date:		Jul 2023
+KernelVersion:	6.6
+Description:
+		This group contains a UMP Function Block configuration.
+		A new block starts from 0, and can be up to 31.
+
+		The attributes:
+
+		===============	===============================================
+		name		Function Block name string
+		direction	1: input, 2: output, 3: bidirectional
+		first_group	The first UMP Group number (0-15)
+		num_groups	The number of groups in this FB (1-16)
+		ui_hint		0: unknown, 1: receiver, 2: sender, 3: both
+		midi_ci_verison	Supported MIDI-CI version number (8 bit)
+		is_midi1	Legacy MIDI 1.0 device (0, 1 or 2)
+		sysex8_streams	Max number of SysEx8 streams (8 bit)
+		active		Active FB flag (0 or 1)
+		===============	===============================================
diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 848cb3150deb..c68a6fa0d237 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -292,7 +292,7 @@ static struct usb_interface_descriptor midi2_midi2_if_desc = {
 	.bDescriptorType =	USB_DT_INTERFACE,
 	.bInterfaceNumber =	0, // to be filled
 	.bAlternateSetting =	1,
-	.bNumEndpoints =	2,
+	.bNumEndpoints =	2, // to be filled
 	.bInterfaceClass =	USB_CLASS_AUDIO,
 	.bInterfaceSubClass =	USB_SUBCLASS_MIDISTREAMING,
 	.bInterfaceProtocol =	0,
@@ -1403,6 +1403,8 @@ static int f_midi2_bind(struct usb_configuration *c, struct usb_function *f)
 				midi2->strings[gtb_to_str_id(ep->blks[blk].gtb_id)].id;
 	}
 
+	midi2_midi2_if_desc.bNumEndpoints = midi2->num_eps * 2;
+
 	/* audio interface */
 	status = usb_interface_id(c, f);
 	if (status < 0)
@@ -1510,16 +1512,274 @@ static void f_midi2_unbind(struct usb_configuration *c, struct usb_function *f)
 	usb_free_all_descriptors(f);
 }
 
+/*
+ * ConfigFS interface
+ */
+
+/* type conversion helpers */
+static inline struct f_midi2_opts *to_f_midi2_opts(struct config_item *item)
+{
+	return container_of(to_config_group(item), struct f_midi2_opts,
+			    func_inst.group);
+}
+
+static inline struct f_midi2_ep_opts *
+to_f_midi2_ep_opts(struct config_item *item)
+{
+	return container_of(to_config_group(item), struct f_midi2_ep_opts,
+			    group);
+}
+
+static inline struct f_midi2_block_opts *
+to_f_midi2_block_opts(struct config_item *item)
+{
+	return container_of(to_config_group(item), struct f_midi2_block_opts,
+			    group);
+}
+
+/* trim the string to be usable for EP and FB name strings */
+static void make_name_string(char *s)
+{
+	char *p;
+
+	p = strchr(s, '\n');
+	if (p)
+		*p = 0;
+
+	p = s + strlen(s);
+	for (; p > s && isspace(*p); p--)
+		*p = 0;
+}
+
+/* configfs helpers: generic show/store for unisnged int */
+static ssize_t f_midi2_opts_uint_show(struct f_midi2_opts *opts,
+				      u32 val, const char *format, char *page)
+{
+	int result;
+
+	mutex_lock(&opts->lock);
+	result = sprintf(page, format, val);
+	mutex_unlock(&opts->lock);
+	return result;
+}
+
+static ssize_t f_midi2_opts_uint_store(struct f_midi2_opts *opts,
+				       u32 *valp, u32 minval, u32 maxval,
+				       const char *page, size_t len)
+{
+	int ret;
+	u32 val;
+
+	mutex_lock(&opts->lock);
+	if (opts->refcnt) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	ret = kstrtou32(page, 0, &val);
+	if (ret)
+		goto end;
+	if (val < minval || val > maxval) {
+		ret = -EINVAL;
+		goto end;
+	}
+
+	*valp = val;
+	ret = len;
+
+end:
+	mutex_unlock(&opts->lock);
+	return ret;
+}
+
+/* generic store for bool */
+static ssize_t f_midi2_opts_bool_store(struct f_midi2_opts *opts,
+				       bool *valp, const char *page, size_t len)
+{
+	int ret;
+	bool val;
+
+	mutex_lock(&opts->lock);
+	if (opts->refcnt) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	ret = kstrtobool(page, &val);
+	if (ret)
+		goto end;
+	*valp = val;
+	ret = len;
+
+end:
+	mutex_unlock(&opts->lock);
+	return ret;
+}
+
+/* generic show/store for string */
+static ssize_t f_midi2_opts_str_show(struct f_midi2_opts *opts,
+				     const char *str, char *page)
+{
+	int result = 0;
+
+	mutex_lock(&opts->lock);
+	if (str)
+		result = scnprintf(page, PAGE_SIZE, "%s\n", str);
+	mutex_unlock(&opts->lock);
+	return result;
+}
+
+static ssize_t f_midi2_opts_str_store(struct f_midi2_opts *opts,
+				      const char **strp, size_t maxlen,
+				      const char *page, size_t len)
+{
+	char *c;
+	int ret;
+
+	mutex_lock(&opts->lock);
+	if (opts->refcnt) {
+		ret = -EBUSY;
+		goto end;
+	}
+
+	c = kstrndup(page, min(len, maxlen), GFP_KERNEL);
+	if (!c) {
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	kfree(*strp);
+	make_name_string(c);
+	*strp = c;
+	ret = len;
+
+end:
+	mutex_unlock(&opts->lock);
+	return ret;
+}
+
+/*
+ * Definitions for UMP Block config
+ */
+
+/* define an uint option for block */
+#define F_MIDI2_BLOCK_OPT(name, format, minval, maxval)			\
+static ssize_t f_midi2_block_opts_##name##_show(struct config_item *item,\
+					  char *page)			\
+{									\
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);	\
+	return f_midi2_opts_uint_show(opts->ep->opts, opts->info.name,	\
+				      format "\n", page);		\
+}									\
+									\
+static ssize_t f_midi2_block_opts_##name##_store(struct config_item *item,\
+					 const char *page, size_t len)	\
+{									\
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);	\
+	return f_midi2_opts_uint_store(opts->ep->opts, &opts->info.name,\
+				       minval, maxval, page, len);	\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_block_opts_, name)
+
+/* define a boolean option for block */
+#define F_MIDI2_BLOCK_BOOL_OPT(name)					\
+static ssize_t f_midi2_block_opts_##name##_show(struct config_item *item,\
+					  char *page)			\
+{									\
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);	\
+	return f_midi2_opts_uint_show(opts->ep->opts, opts->info.name,	\
+				      "%u\n", page);			\
+}									\
+									\
+static ssize_t f_midi2_block_opts_##name##_store(struct config_item *item,\
+					 const char *page, size_t len)	\
+{									\
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);	\
+	return f_midi2_opts_bool_store(opts->ep->opts, &opts->info.name,\
+				       page, len);			\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_block_opts_, name)
+
+F_MIDI2_BLOCK_OPT(direction, "0x%x", 1, 3);
+F_MIDI2_BLOCK_OPT(first_group, "0x%x", 0, 15);
+F_MIDI2_BLOCK_OPT(num_groups, "0x%x", 1, 16);
+F_MIDI2_BLOCK_OPT(ui_hint, "0x%x", 0, 3);
+F_MIDI2_BLOCK_OPT(midi_ci_version, "%u", 0, 1);
+F_MIDI2_BLOCK_OPT(sysex8_streams, "%u", 0, 255);
+F_MIDI2_BLOCK_OPT(is_midi1, "%u", 0, 2);
+F_MIDI2_BLOCK_BOOL_OPT(active);
+
+static ssize_t f_midi2_block_opts_name_show(struct config_item *item,
+					    char *page)
+{
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
+
+	return f_midi2_opts_str_show(opts->ep->opts, opts->info.name, page);
+}
+
+static ssize_t f_midi2_block_opts_name_store(struct config_item *item,
+					     const char *page, size_t len)
+{
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
+
+	return f_midi2_opts_str_store(opts->ep->opts, &opts->info.name, 128,
+				      page, len);
+}
+
+CONFIGFS_ATTR(f_midi2_block_opts_, name);
+
+static struct configfs_attribute *f_midi2_block_attrs[] = {
+	&f_midi2_block_opts_attr_direction,
+	&f_midi2_block_opts_attr_first_group,
+	&f_midi2_block_opts_attr_num_groups,
+	&f_midi2_block_opts_attr_ui_hint,
+	&f_midi2_block_opts_attr_midi_ci_version,
+	&f_midi2_block_opts_attr_sysex8_streams,
+	&f_midi2_block_opts_attr_is_midi1,
+	&f_midi2_block_opts_attr_active,
+	&f_midi2_block_opts_attr_name,
+	NULL,
+};
+
+static void f_midi2_block_opts_release(struct config_item *item)
+{
+	struct f_midi2_block_opts *opts = to_f_midi2_block_opts(item);
+
+	kfree(opts->info.name);
+	kfree(opts);
+}
+
+static struct configfs_item_operations f_midi2_block_item_ops = {
+	.release	= f_midi2_block_opts_release,
+};
+
+static const struct config_item_type f_midi2_block_type = {
+	.ct_item_ops	= &f_midi2_block_item_ops,
+	.ct_attrs	= f_midi2_block_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
 /* create a f_midi2_block_opts instance for the given block number */
 static int f_midi2_block_opts_create(struct f_midi2_ep_opts *ep_opts,
 				     unsigned int blk,
 				     struct f_midi2_block_opts **block_p)
 {
 	struct f_midi2_block_opts *block_opts;
+	int ret = 0;
+
+	mutex_lock(&ep_opts->opts->lock);
+	if (ep_opts->opts->refcnt || ep_opts->blks[blk]) {
+		ret = -EBUSY;
+		goto out;
+	}
 
 	block_opts = kzalloc(sizeof(*block_opts), GFP_KERNEL);
-	if (!block_opts)
-		return -ENOMEM;
+	if (!block_opts) {
+		ret = -ENOMEM;
+		goto out;
+	}
 
 	block_opts->ep = ep_opts;
 	block_opts->id = blk;
@@ -1533,9 +1793,143 @@ static int f_midi2_block_opts_create(struct f_midi2_ep_opts *ep_opts,
 
 	ep_opts->blks[blk] = block_opts;
 	*block_p = block_opts;
-	return 0;
+
+	mutex_unlock(&ep_opts->opts->lock);
+ out:
+	return ret;
 }
 
+/* make_group callback for a block */
+static struct config_group *
+f_midi2_opts_block_make(struct config_group *group, const char *name)
+{
+	struct f_midi2_ep_opts *ep_opts;
+	struct f_midi2_block_opts *block_opts;
+	unsigned int blk;
+	int ret;
+
+	if (strncmp(name, "block.", 6))
+		return ERR_PTR(-EINVAL);
+	ret = kstrtouint(name + 6, 10, &blk);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ep_opts = to_f_midi2_ep_opts(&group->cg_item);
+
+	if (blk >= SNDRV_UMP_MAX_BLOCKS)
+		return ERR_PTR(-EINVAL);
+	if (ep_opts->blks[blk])
+		return ERR_PTR(-EBUSY);
+	ret = f_midi2_block_opts_create(ep_opts, blk, &block_opts);
+	if (ret)
+		return ERR_PTR(ret);
+
+	config_group_init_type_name(&block_opts->group, name,
+				    &f_midi2_block_type);
+	return &block_opts->group;
+}
+
+/* drop_item callback for a block */
+static void
+f_midi2_opts_block_drop(struct config_group *group, struct config_item *item)
+{
+	struct f_midi2_block_opts *block_opts = to_f_midi2_block_opts(item);
+
+	mutex_lock(&block_opts->ep->opts->lock);
+	block_opts->ep->blks[block_opts->id] = NULL;
+	mutex_unlock(&block_opts->ep->opts->lock);
+	config_item_put(item);
+}
+
+/*
+ * Definitions for UMP Endpoint config
+ */
+
+/* define an uint option for EP */
+#define F_MIDI2_EP_OPT(name, format, minval, maxval)			\
+static ssize_t f_midi2_ep_opts_##name##_show(struct config_item *item,	\
+					     char *page)		\
+{									\
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);	\
+	return f_midi2_opts_uint_show(opts->opts, opts->info.name,	\
+				      format "\n", page);		\
+}									\
+									\
+static ssize_t f_midi2_ep_opts_##name##_store(struct config_item *item,	\
+					   const char *page, size_t len)\
+{									\
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);	\
+	return f_midi2_opts_uint_store(opts->opts, &opts->info.name,	\
+				       minval, maxval, page, len);	\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_ep_opts_, name)
+
+/* define a string option for EP */
+#define F_MIDI2_EP_STR_OPT(name, maxlen)				\
+static ssize_t f_midi2_ep_opts_##name##_show(struct config_item *item,	\
+					     char *page)		\
+{									\
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);	\
+	return f_midi2_opts_str_show(opts->opts, opts->info.name, page);\
+}									\
+									\
+static ssize_t f_midi2_ep_opts_##name##_store(struct config_item *item,	\
+					 const char *page, size_t len)	\
+{									\
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);	\
+	return f_midi2_opts_str_store(opts->opts, &opts->info.name, maxlen,\
+				      page, len);			\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_ep_opts_, name)
+
+F_MIDI2_EP_OPT(protocol, "0x%x", 1, 2);
+F_MIDI2_EP_OPT(protocol_caps, "0x%x", 1, 3);
+F_MIDI2_EP_OPT(manufacturer, "0x%x", 0, 0xffffff);
+F_MIDI2_EP_OPT(family, "0x%x", 0, 0xffff);
+F_MIDI2_EP_OPT(model, "0x%x", 0, 0xffff);
+F_MIDI2_EP_OPT(sw_revision, "0x%x", 0, 0xffffffff);
+F_MIDI2_EP_STR_OPT(ep_name, 128);
+F_MIDI2_EP_STR_OPT(product_id, 128);
+
+static struct configfs_attribute *f_midi2_ep_attrs[] = {
+	&f_midi2_ep_opts_attr_protocol,
+	&f_midi2_ep_opts_attr_protocol_caps,
+	&f_midi2_ep_opts_attr_ep_name,
+	&f_midi2_ep_opts_attr_product_id,
+	&f_midi2_ep_opts_attr_manufacturer,
+	&f_midi2_ep_opts_attr_family,
+	&f_midi2_ep_opts_attr_model,
+	&f_midi2_ep_opts_attr_sw_revision,
+	NULL,
+};
+
+static void f_midi2_ep_opts_release(struct config_item *item)
+{
+	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
+
+	kfree(opts->info.ep_name);
+	kfree(opts->info.product_id);
+	kfree(opts);
+}
+
+static struct configfs_item_operations f_midi2_ep_item_ops = {
+	.release	= f_midi2_ep_opts_release,
+};
+
+static struct configfs_group_operations f_midi2_ep_group_ops = {
+	.make_group	= f_midi2_opts_block_make,
+	.drop_item	= f_midi2_opts_block_drop,
+};
+
+static const struct config_item_type f_midi2_ep_type = {
+	.ct_item_ops	= &f_midi2_ep_item_ops,
+	.ct_group_ops	= &f_midi2_ep_group_ops,
+	.ct_attrs	= f_midi2_ep_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
 /* create a f_midi2_ep_opts instance */
 static int f_midi2_ep_opts_create(struct f_midi2_opts *opts,
 				  unsigned int index,
@@ -1559,7 +1953,119 @@ static int f_midi2_ep_opts_create(struct f_midi2_opts *opts,
 	return 0;
 }
 
+/* make_group callback for an EP */
+static struct config_group *
+f_midi2_opts_ep_make(struct config_group *group, const char *name)
+{
+	struct f_midi2_opts *opts;
+	struct f_midi2_ep_opts *ep_opts;
+	unsigned int index;
+	int ret;
+
+	if (strncmp(name, "ep.", 3))
+		return ERR_PTR(-EINVAL);
+	ret = kstrtouint(name + 3, 10, &index);
+	if (ret)
+		return ERR_PTR(ret);
+
+	opts = to_f_midi2_opts(&group->cg_item);
+	if (index >= MAX_UMP_EPS)
+		return ERR_PTR(-EINVAL);
+	if (opts->eps[index])
+		return ERR_PTR(-EBUSY);
+	ret = f_midi2_ep_opts_create(opts, index, &ep_opts);
+	if (ret)
+		return ERR_PTR(ret);
+
+	config_group_init_type_name(&ep_opts->group, name, &f_midi2_ep_type);
+	return &ep_opts->group;
+}
+
+/* drop_item callback for an EP */
+static void
+f_midi2_opts_ep_drop(struct config_group *group, struct config_item *item)
+{
+	struct f_midi2_ep_opts *ep_opts = to_f_midi2_ep_opts(item);
+
+	mutex_lock(&ep_opts->opts->lock);
+	ep_opts->opts->eps[ep_opts->index] = NULL;
+	mutex_unlock(&ep_opts->opts->lock);
+	config_item_put(item);
+}
+
+/*
+ * Definitions for card config
+ */
+
+/* define a bool option for card */
+#define F_MIDI2_BOOL_OPT(name)						\
+static ssize_t f_midi2_opts_##name##_show(struct config_item *item,	\
+					  char *page)			\
+{									\
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);		\
+	return f_midi2_opts_uint_show(opts, opts->info.name,		\
+				      "%u\n", page);			\
+}									\
+									\
+static ssize_t f_midi2_opts_##name##_store(struct config_item *item,	\
+					 const char *page, size_t len)	\
+{									\
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);		\
+	return f_midi2_opts_bool_store(opts, &opts->info.name,		\
+				       page, len);			\
+}									\
+									\
+CONFIGFS_ATTR(f_midi2_opts_, name)
+
+F_MIDI2_BOOL_OPT(process_ump);
+F_MIDI2_BOOL_OPT(static_block);
+
+static ssize_t f_midi2_opts_iface_name_show(struct config_item *item,
+					    char *page)
+{
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);
+
+	return f_midi2_opts_str_show(opts, opts->info.iface_name, page);
+}
+
+static ssize_t f_midi2_opts_iface_name_store(struct config_item *item,
+					     const char *page, size_t len)
+{
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);
+
+	return f_midi2_opts_str_store(opts, &opts->info.iface_name, 128,
+				      page, len);
+}
+
+CONFIGFS_ATTR(f_midi2_opts_, iface_name);
+
+static struct configfs_attribute *f_midi2_attrs[] = {
+	&f_midi2_opts_attr_process_ump,
+	&f_midi2_opts_attr_static_block,
+	&f_midi2_opts_attr_iface_name,
+	NULL
+};
+
+static void f_midi2_opts_release(struct config_item *item)
+{
+	struct f_midi2_opts *opts = to_f_midi2_opts(item);
+
+	usb_put_function_instance(&opts->func_inst);
+}
+
+static struct configfs_item_operations f_midi2_item_ops = {
+	.release	= f_midi2_opts_release,
+};
+
+static struct configfs_group_operations f_midi2_group_ops = {
+	.make_group	= f_midi2_opts_ep_make,
+	.drop_item	= f_midi2_opts_ep_drop,
+};
+
 static const struct config_item_type f_midi2_func_type = {
+	.ct_item_ops	= &f_midi2_item_ops,
+	.ct_group_ops	= &f_midi2_group_ops,
+	.ct_attrs	= f_midi2_attrs,
 	.ct_owner	= THIS_MODULE,
 };
 
@@ -1569,11 +2075,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
-	/* we have only one EP and one FB */
-	if (opts->eps[0]) {
-		kfree(opts->eps[0]->blks[0]);
-		kfree(opts->eps[0]);
-	}
+	kfree(opts->info.iface_name);
 	kfree(opts);
 }
 
@@ -1596,6 +2098,7 @@ static struct usb_function_instance *f_midi2_alloc_inst(void)
 	opts->info.num_reqs = 32;
 	opts->info.req_buf_size = 512;
 
+	/* create the default ep */
 	ret = f_midi2_ep_opts_create(opts, 0, &ep_opts);
 	if (ret) {
 		kfree(opts);
@@ -1612,6 +2115,15 @@ static struct usb_function_instance *f_midi2_alloc_inst(void)
 
 	config_group_init_type_name(&opts->func_inst.group, "",
 				    &f_midi2_func_type);
+
+	config_group_init_type_name(&ep_opts->group, "ep.0",
+				    &f_midi2_ep_type);
+	configfs_add_default_group(&ep_opts->group, &opts->func_inst.group);
+
+	config_group_init_type_name(&block_opts->group, "block.0",
+				    &f_midi2_block_type);
+	configfs_add_default_group(&block_opts->group, &ep_opts->group);
+
 	return &opts->func_inst;
 }
 
@@ -1630,12 +2142,58 @@ static void f_midi2_free(struct usb_function *f)
 			container_of(f->fi, struct f_midi2_opts, func_inst));
 }
 
+/* verify the parameters set up via configfs;
+ * return the number of EPs or a negative error
+ */
+static int verify_parameters(struct f_midi2_opts *opts)
+{
+	int i, j, num_eps, num_blks;
+	struct f_midi2_ep_info *ep;
+	struct f_midi2_block_info *bp;
+
+	for (num_eps = 0; num_eps < MAX_UMP_EPS && opts->eps[num_eps];
+	     num_eps++)
+		;
+	if (!num_eps) {
+		pr_err("f_midi2: No EP is defined\n");
+		return -EINVAL;
+	}
+
+	num_blks = 0;
+	for (i = 0; i < num_eps; i++) {
+		ep = &opts->eps[i]->info;
+		if (!(ep->protocol_caps & ep->protocol)) {
+			pr_err("f_midi2: Invalid protocol 0x%x (caps 0x%x) for EP %d\n",
+			       ep->protocol, ep->protocol_caps, i);
+			return -EINVAL;
+		}
+
+		for (j = 0; j < SNDRV_UMP_MAX_BLOCKS && opts->eps[i]->blks[j];
+		     j++, num_blks++) {
+			bp = &opts->eps[i]->blks[j]->info;
+			if (bp->first_group + bp->num_groups > SNDRV_UMP_MAX_GROUPS) {
+				pr_err("f_midi2: Invalid group definitions for block %d:%d\n",
+				       i, j);
+				return -EINVAL;
+			}
+		}
+	}
+	if (!num_blks) {
+		pr_err("f_midi2: No block is defined\n");
+		return -EINVAL;
+	}
+
+	return num_eps;
+}
+
 /* gadget alloc callback */
 static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
 {
 	struct f_midi2 *midi2;
 	struct f_midi2_opts *opts;
-	int i;
+	struct f_midi2_ep *ep;
+	struct f_midi2_block *bp;
+	int i, num_eps, blk;
 
 	midi2 = kzalloc(sizeof(*midi2), GFP_KERNEL);
 	if (!midi2)
@@ -1643,6 +2201,12 @@ static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
 
 	opts = container_of(fi, struct f_midi2_opts, func_inst);
 	mutex_lock(&opts->lock);
+	num_eps = verify_parameters(opts);
+	if (num_eps < 0) {
+		mutex_unlock(&opts->lock);
+		kfree(midi2);
+		return ERR_PTR(num_eps);
+	}
 	++opts->refcnt;
 	mutex_unlock(&opts->lock);
 
@@ -1658,17 +2222,20 @@ static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
 	midi2->func.free_func = f_midi2_free;
 
 	midi2->info = opts->info;
+	midi2->num_eps = num_eps;
 
-	/* fixed 1 UMP EP and 1 UMP FB as of now */
-	midi2->num_eps = 1;
-	midi2->midi2_eps[0].info = opts->eps[0]->info;
-	midi2->midi2_eps[0].card = midi2;
-	midi2->midi2_eps[0].num_blks = 1;
-	midi2->midi2_eps[0].blks[0].info = opts->eps[0]->blks[0]->info;
-	midi2->midi2_eps[0].blks[0].gtb_id = 1;
-
-	for (i = 0; i < midi2->num_eps; i++)
-		midi2->total_blocks += midi2->midi2_eps[i].num_blks;
+	for (i = 0; i < num_eps; i++) {
+		ep = &midi2->midi2_eps[i];
+		ep->info = opts->eps[i]->info;
+		ep->card = midi2;
+		for (blk = 0; blk < SNDRV_UMP_MAX_BLOCKS &&
+			     opts->eps[i]->blks[blk]; blk++) {
+			bp = &ep->blks[blk];
+			ep->num_blks++;
+			bp->info = opts->eps[i]->blks[blk]->info;
+			bp->gtb_id = ++midi2->total_blocks;
+		}
+	}
 
 	midi2->string_defs = kcalloc(midi2->total_blocks + 1,
 				     sizeof(*midi2->string_defs), GFP_KERNEL);
@@ -1678,10 +2245,18 @@ static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi)
 	}
 
 	if (opts->info.iface_name && *opts->info.iface_name)
-		midi2->string_defs[0].s = opts->info.iface_name;
+		midi2->string_defs[STR_IFACE].s = opts->info.iface_name;
 	else
-		midi2->string_defs[0].s = ump_ep_name(&midi2->midi2_eps[0]);
-	midi2->string_defs[1].s = ump_fb_name(&midi2->midi2_eps[0].blks[0].info);
+		midi2->string_defs[STR_IFACE].s = ump_ep_name(&midi2->midi2_eps[0]);
+
+	for (i = 0; i < midi2->num_eps; i++) {
+		ep = &midi2->midi2_eps[i];
+		for (blk = 0; blk < ep->num_blks; blk++) {
+			bp = &ep->blks[blk];
+			midi2->string_defs[gtb_to_str_id(bp->gtb_id)].s =
+				ump_fb_name(&bp->info);
+		}
+	}
 
 	return &midi2->func;
 }
]

390/2 2026/07/30 15:10 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 38168
							output: 45
							thoughts: 580
						

Thoughts:
**Analyzing the MIDI2 Configfs Integration**

Okay, so I'm looking at commit `29ee7a4dddd5caa18d1cef000f20c6af43f762f1` – this is the one that introduced configfs support for the MIDI2 function. I see the key change is within `f_midi2_alloc_inst`. It now initializes and adds groups to the configfs hierarchy using `config_group_init_type_name` and `configfs_add_default_group`. Specifically, it creates "ep.0" and "block.0" groups within the configfs structure. This is pretty standard for integrating a function with configfs – define the groups and their associated types.

The interesting part is the modification to `f_midi2_free_inst`. Originally, it looks like this function was responsible for freeing the `eps` and `blks` that were allocated. The commit removes those lines. My initial concern here is that there's no corresponding `configfs_remove_default_groups` call added within `f_midi2_free_inst` in this commit. Now that the configfs is integrated, this could leak the default groups. I need to make sure this is being handled correctly elsewhere.

I also notice that the `f_midi2_ep_opts_release` function was added in this commit. I suspect that this is where the resources associated with the configfs groups are being cleaned up. Since I'm not seeing it in `f_midi2_free_inst`, I need to confirm this. I will verify if this function has been appropriately implemented. Let me check the subsequent commits to see if `8b645922b22303cec4628dbbbf6c8553d1cdec87` added this functionality.



391/2 2026/07/30 15:11 tool grepper
0m Args:
map[Expression:f_midi2_ep_opts_release PathPrefix:drivers/usb/gadget/function/f_midi2.c]

Results:
map[Output:drivers/usb/gadget/function/f_midi2.c=2460=static struct configfs_attribute *f_midi2_ep_attrs[] = {
--
drivers/usb/gadget/function/f_midi2.c-2471-
drivers/usb/gadget/function/f_midi2.c:2472:static void f_midi2_ep_opts_release(struct config_item *item)
drivers/usb/gadget/function/f_midi2.c-2473-{
--
drivers/usb/gadget/function/f_midi2.c=2481=static const struct configfs_item_operations f_midi2_ep_item_ops = {
drivers/usb/gadget/function/f_midi2.c:2482:	.release	= f_midi2_ep_opts_release,
drivers/usb/gadget/function/f_midi2.c-2483-};
]

392/2 2026/07/30 15:11 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 39443
							output: 49
							thoughts: 109
						

Thoughts:
**Checking for Recent Code Changes**

Okay, so I just did a `grep` in the current working tree, but I need to make sure I'm looking at the right commits. The current search might be missing something. Specifically, I need to check if commit `8b645922b22303cec4628dbbbf6c8553d1cdec87` actually introduced or modified `f_midi2_ep_opts_release`. Let me pull up the diff for that commit again to get a clear picture. Gotta be precise here; I don't want to waste time chasing ghosts.



393/2 2026/07/30 15:11 tool git-show
0m Args:
map[Commit:8b645922b22303cec4628dbbbf6c8553d1cdec87]

Results:
map[Output:
Full output is too long, showing 1000 out of 1877 lines.

[commit 8b645922b22303cec4628dbbbf6c8553d1cdec87
 Author: Takashi Iwai <tiwai@suse.de>
 Date:   Tue Jul 25 08:22:00 2023 +0200
 
     usb: gadget: Add support for USB MIDI 2.0 function driver
     
     This patch adds the support for USB MIDI 2.0 gadget function driver.
     The driver emulates a USB MIDI 2.0 interface with one or more UMP
     Endpoints, where each of UMP Endpoint is a pair of MIDI Endpoints for
     handling MIDI 2.0 UMP packets.  When the function driver is bound, the
     driver creates an ALSA card object with UMP rawmidi devices.  This is
     a kind of loop-back where the incoming and upcoming UMP packets
     from/to the MIDI 2.0 UMP Endpoints are transferred as-is.  In
     addition, legacy (MIDI 1.0) rawmidi devices are created, so that
     legacy applications can work in the gadget side, too.
     
     When a USB MIDI 2.0 gadget interface appears, the connected host can
     use it with the snd-usb-audio driver where MIDI 2.0 support is
     enabled.  Both gadget and connected hosts will have the similar UMP
     Endpoint and Function Block (or Group Terminal Block) information.
     Slight differences are the direction and UI-hint bits; it's due to the
     nature of gadget driver, and the input/output direction is swapped in
     both sides (the input for gadget is the output for host, and vice
     versa).
     
     The driver supports the brand-new UMP v1.1 feature, including the UMP
     Stream message handling for providing UMP Endpoint and Function Block
     information as well as dealing with the MIDI protocol switch.  The
     driver responds to UMP Stream messages by itself.  OTOH, MIDI-CI
     message handling isn't implemented in the kernel driver; it should be
     processed in the user-space through the loopback UMP device.
     
     As of this patch, the whole configuration is fixed, providing only one
     bidirectional UMP Endpoint containing a single FB/GTB with a single
     UMP Group.  The configuration will be dynamically changeable in the
     following patches.
     
     The traditional MIDI 1.0 is still provided in the altset 0 (which is
     mandatory per spec).  But it's only about the configuration, and no
     actual I/O will be running for the altset 0 as of this patch.  The
     proper support MIDI 1.0 altset will follow in later patches, too.
     
     Signed-off-by: Takashi Iwai <tiwai@suse.de>
     Link: https://lore.kernel.org/r/20230725062206.9674-2-tiwai@suse.de
     Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
 index 336db8f92afa..b3592bcb0f96 100644
 --- a/drivers/usb/gadget/Kconfig
 +++ b/drivers/usb/gadget/Kconfig
 @@ -208,6 +208,9 @@ config USB_F_UVC
  config USB_F_MIDI
  	tristate
  
 +config USB_F_MIDI2
 +	tristate
 +
  config USB_F_HID
  	tristate
  
 @@ -436,6 +439,21 @@ config USB_CONFIGFS_F_MIDI
  	  connections can then be made on the gadget system, using
  	  ALSA's aconnect utility etc.
  
 +config USB_CONFIGFS_F_MIDI2
 +	bool "MIDI 2.0 function"
 +	depends on USB_CONFIGFS
 +	depends on SND
 +	select USB_LIBCOMPOSITE
 +	select SND_UMP
 +	select SND_UMP_LEGACY_RAWMIDI
 +	select USB_F_MIDI2
 +	help
 +	  The MIDI 2.0 function driver provides the generic emulated
 +	  USB MIDI 2.0 interface, looped back to ALSA UMP rawmidi
 +	  device on the gadget host. It supports UMP 1.1 spec and
 +	  responds UMP Stream messages for UMP Endpoint and Function
 +	  Block information / configuration.
 +
  config USB_CONFIGFS_F_HID
  	bool "HID function"
  	depends on USB_CONFIGFS
 diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile
 index 5d3a6cf02218..87917a7d4a9b 100644
 --- a/drivers/usb/gadget/function/Makefile
 +++ b/drivers/usb/gadget/function/Makefile
 @@ -44,6 +44,8 @@ usb_f_uvc-y			:= f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o
  obj-$(CONFIG_USB_F_UVC)		+= usb_f_uvc.o
  usb_f_midi-y			:= f_midi.o
  obj-$(CONFIG_USB_F_MIDI)	+= usb_f_midi.o
 +usb_f_midi2-y			:= f_midi2.o
 +obj-$(CONFIG_USB_F_MIDI2)	+= usb_f_midi2.o
  usb_f_hid-y			:= f_hid.o
  obj-$(CONFIG_USB_F_HID)		+= usb_f_hid.o
  usb_f_printer-y			:= f_printer.o
 diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
 new file mode 100644
 index 000000000000..848cb3150deb
 --- /dev/null
 +++ b/drivers/usb/gadget/function/f_midi2.c
 @@ -0,0 +1,1691 @@
 +// SPDX-License-Identifier: GPL-2.0+
 +/*
 + * f_midi2.c -- USB MIDI 2.0 class function driver
 + */
 +
 +#include <linux/device.h>
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/slab.h>
 +
 +#include <sound/core.h>
 +#include <sound/ump.h>
 +#include <sound/ump_msg.h>
 +
 +#include <linux/usb/ch9.h>
 +#include <linux/usb/gadget.h>
 +#include <linux/usb/audio.h>
 +#include <linux/usb/midi-v2.h>
 +
 +#include "u_f.h"
 +#include "u_midi2.h"
 +
 +struct f_midi2;
 +struct f_midi2_ep;
 +struct f_midi2_usb_ep;
 +
 +/* Context for each USB request */
 +struct f_midi2_req_ctx {
 +	struct f_midi2_usb_ep *usb_ep;	/* belonging USB EP */
 +	unsigned int index;		/* array index: 0-31 */
 +	struct usb_request *req;	/* assigned request */
 +};
 +
 +/* Resources for a USB Endpoint */
 +struct f_midi2_usb_ep {
 +	struct f_midi2 *card;		/* belonging card */
 +	struct f_midi2_ep *ep;		/* belonging UMP EP (optional) */
 +	struct usb_ep *usb_ep;		/* assigned USB EP */
 +	void (*complete)(struct usb_ep *usb_ep, struct usb_request *req);
 +	unsigned long free_reqs;	/* bitmap for unused requests */
 +	unsigned int num_reqs;		/* number of allocated requests */
 +	struct f_midi2_req_ctx *reqs;	/* request context array */
 +};
 +
 +/* Resources for UMP Function Block (and USB Group Terminal Block) */
 +struct f_midi2_block {
 +	struct f_midi2_block_info info;	/* FB info, copied from configfs */
 +	struct snd_ump_block *fb;	/* assigned FB */
 +	unsigned int gtb_id;		/* assigned GTB id */
 +	unsigned int string_id;		/* assigned string id */
 +};
 +
 +/* Resources for UMP Endpoint */
 +struct f_midi2_ep {
 +	struct snd_ump_endpoint *ump;	/* assigned UMP EP */
 +	struct f_midi2 *card;		/* belonging MIDI 2.0 device */
 +
 +	struct f_midi2_ep_info info;	/* UMP EP info, copied from configfs */
 +	unsigned int num_blks;		/* number of FBs */
 +	struct f_midi2_block blks[SNDRV_UMP_MAX_BLOCKS];	/* UMP FBs */
 +
 +	struct f_midi2_usb_ep ep_in;	/* USB MIDI EP-in */
 +	struct f_midi2_usb_ep ep_out;	/* USB MIDI EP-out */
 +};
 +
 +/* indices for USB strings */
 +enum {
 +	STR_IFACE = 0,
 +	STR_GTB1 = 1,
 +};
 +
 +/* 1-based GTB id to string id */
 +#define gtb_to_str_id(id)	(STR_GTB1 + (id) - 1)
 +
 +/* operation mode */
 +enum {
 +	MIDI_OP_MODE_UNSET,	/* no altset set yet */
 +	MIDI_OP_MODE_MIDI1,	/* MIDI 1.0 (altset 0) is used */
 +	MIDI_OP_MODE_MIDI2,	/* MIDI 2.0 (altset 1) is used */
 +};
 +
 +/* Resources for MIDI 2.0 Device */
 +struct f_midi2 {
 +	struct usb_function func;
 +	struct usb_gadget *gadget;
 +	struct snd_card *card;
 +
 +	/* MIDI 1.0 in/out USB EPs */
 +	struct f_midi2_usb_ep midi1_ep_in;
 +	struct f_midi2_usb_ep midi1_ep_out;
 +
 +	int midi_if;			/* USB MIDI interface number */
 +	int operation_mode;		/* current operation mode */
 +
 +	spinlock_t queue_lock;
 +
 +	struct f_midi2_card_info info;	/* card info, copied from configfs */
 +
 +	unsigned int num_eps;
 +	struct f_midi2_ep midi2_eps[MAX_UMP_EPS];
 +
 +	unsigned int total_blocks;	/* total number of blocks of all EPs */
 +	struct usb_string *string_defs;
 +	struct usb_string *strings;
 +};
 +
 +#define func_to_midi2(f)	container_of(f, struct f_midi2, func)
 +
 +/* get EP name string */
 +static const char *ump_ep_name(const struct f_midi2_ep *ep)
 +{
 +	return ep->info.ep_name ? ep->info.ep_name : "MIDI 2.0 Gadget";
 +}
 +
 +/* get EP product ID string */
 +static const char *ump_product_id(const struct f_midi2_ep *ep)
 +{
 +	return ep->info.product_id ? ep->info.product_id : "Unique Product ID";
 +}
 +
 +/* get FB name string */
 +static const char *ump_fb_name(const struct f_midi2_block_info *info)
 +{
 +	return info->name ? info->name : "MIDI 2.0 Gadget I/O";
 +}
 +
 +/*
 + * USB Descriptor Definitions
 + */
 +/* GTB header descriptor */
 +static struct usb_ms20_gr_trm_block_header_descriptor gtb_header_desc = {
 +	.bLength =		sizeof(gtb_header_desc),
 +	.bDescriptorType =	USB_DT_CS_GR_TRM_BLOCK,
 +	.bDescriptorSubtype =	USB_MS_GR_TRM_BLOCK_HEADER,
 +	.wTotalLength =		__cpu_to_le16(0x12), // to be filled
 +};
 +
 +/* GTB descriptor template: most items are replaced dynamically */
 +static struct usb_ms20_gr_trm_block_descriptor gtb_desc = {
 +	.bLength =		sizeof(gtb_desc),
 +	.bDescriptorType =	USB_DT_CS_GR_TRM_BLOCK,
 +	.bDescriptorSubtype =	USB_MS_GR_TRM_BLOCK,
 +	.bGrpTrmBlkID =		0x01,
 +	.bGrpTrmBlkType =	USB_MS_GR_TRM_BLOCK_TYPE_BIDIRECTIONAL,
 +	.nGroupTrm =		0x00,
 +	.nNumGroupTrm =		1,
 +	.iBlockItem =		0,
 +	.bMIDIProtocol =	USB_MS_MIDI_PROTO_1_0_64,
 +	.wMaxInputBandwidth =	0,
 +	.wMaxOutputBandwidth =	0,
 +};
 +
 +DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
 +DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1);
 +DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
 +DECLARE_USB_MS20_ENDPOINT_DESCRIPTOR(32);
 +
 +#define EP_MAX_PACKET_INT	8
 +
 +/* Audio Control Interface */
 +static struct usb_interface_descriptor midi2_audio_if_desc = {
 +	.bLength =		USB_DT_INTERFACE_SIZE,
 +	.bDescriptorType =	USB_DT_INTERFACE,
 +	.bInterfaceNumber =	0, // to be filled
 +	.bNumEndpoints =	0,
 +	.bInterfaceClass =	USB_CLASS_AUDIO,
 +	.bInterfaceSubClass =	USB_SUBCLASS_AUDIOCONTROL,
 +	.bInterfaceProtocol =	0,
 +	.iInterface =		0,
 +};
 +
 +static struct uac1_ac_header_descriptor_1 midi2_audio_class_desc = {
 +	.bLength =		0x09,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	0x01,
 +	.bcdADC =		__cpu_to_le16(0x0100),
 +	.wTotalLength =		__cpu_to_le16(0x0009),
 +	.bInCollection =	0x01,
 +	.baInterfaceNr =	{ 0x01 }, // to be filled
 +};
 +
 +/* MIDI 1.0 Streaming Interface (altset 0) */
 +static struct usb_interface_descriptor midi2_midi1_if_desc = {
 +	.bLength =		USB_DT_INTERFACE_SIZE,
 +	.bDescriptorType =	USB_DT_INTERFACE,
 +	.bInterfaceNumber =	0, // to be filled
 +	.bAlternateSetting =	0,
 +	.bNumEndpoints =	2,
 +	.bInterfaceClass =	USB_CLASS_AUDIO,
 +	.bInterfaceSubClass =	USB_SUBCLASS_MIDISTREAMING,
 +	.bInterfaceProtocol =	0,
 +	.iInterface =		0, // to be filled
 +};
 +
 +static struct usb_ms_header_descriptor midi2_midi1_class_desc = {
 +	.bLength =		0x07,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_HEADER,
 +	.bcdMSC =		__cpu_to_le16(0x0100),
 +	.wTotalLength =		__cpu_to_le16(0x41), // to be calculated
 +};
 +
 +/* MIDI 1.0 IN (Embedded) Jack */
 +static struct usb_midi_in_jack_descriptor midi2_midi1_in_jack1_desc = {
 +	.bLength =		0x06,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_MIDI_IN_JACK,
 +	.bJackType =		USB_MS_EMBEDDED,
 +	.bJackID =		0x01,
 +	.iJack =		0,
 +};
 +
 +/* MIDI 1.0 IN (External) Jack */
 +static struct usb_midi_in_jack_descriptor midi2_midi1_in_jack2_desc = {
 +	.bLength =		0x06,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_MIDI_IN_JACK,
 +	.bJackType =		USB_MS_EXTERNAL,
 +	.bJackID =		0x02,
 +	.iJack =		0,
 +};
 +
 +/* MIDI 1.0 OUT (Embedded) Jack */
 +static struct usb_midi_out_jack_descriptor_1 midi2_midi1_out_jack1_desc = {
 +	.bLength =		0x09,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_MIDI_OUT_JACK,
 +	.bJackType =		USB_MS_EMBEDDED,
 +	.bJackID =		0x03,
 +	.bNrInputPins =		1,
 +	.pins =			{ { 0x02, 0x01 } },
 +	.iJack =		0,
 +};
 +
 +/* MIDI 1.0 OUT (External) Jack */
 +static struct usb_midi_out_jack_descriptor_1 midi2_midi1_out_jack2_desc = {
 +	.bLength =		0x09,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_MIDI_OUT_JACK,
 +	.bJackType =		USB_MS_EXTERNAL,
 +	.bJackID =		0x04,
 +	.bNrInputPins =		1,
 +	.pins =			{ { 0x01, 0x01 } },
 +	.iJack =		0,
 +};
 +
 +/* MIDI 1.0 EP OUT */
 +static struct usb_endpoint_descriptor midi2_midi1_ep_out_desc = {
 +	.bLength =		USB_DT_ENDPOINT_AUDIO_SIZE,
 +	.bDescriptorType =	USB_DT_ENDPOINT,
 +	.bEndpointAddress =	USB_DIR_OUT | 0, // set up dynamically
 +	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
 +};
 +
 +static struct usb_ss_ep_comp_descriptor midi2_midi1_ep_out_ss_comp_desc = {
 +	.bLength                = sizeof(midi2_midi1_ep_out_ss_comp_desc),
 +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
 +};
 +
 +static struct usb_ms_endpoint_descriptor_1 midi2_midi1_ep_out_class_desc = {
 +	.bLength =		0x05,
 +	.bDescriptorType =	USB_DT_CS_ENDPOINT,
 +	.bDescriptorSubtype =	USB_MS_GENERAL,
 +	.bNumEmbMIDIJack =	1,
 +	.baAssocJackID =	{ 0x01 },
 +};
 +
 +/* MIDI 1.0 EP IN */
 +static struct usb_endpoint_descriptor midi2_midi1_ep_in_desc = {
 +	.bLength =		USB_DT_ENDPOINT_AUDIO_SIZE,
 +	.bDescriptorType =	USB_DT_ENDPOINT,
 +	.bEndpointAddress =	USB_DIR_IN | 0, // set up dynamically
 +	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
 +};
 +
 +static struct usb_ss_ep_comp_descriptor midi2_midi1_ep_in_ss_comp_desc = {
 +	.bLength                = sizeof(midi2_midi1_ep_in_ss_comp_desc),
 +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
 +};
 +
 +static struct usb_ms_endpoint_descriptor_1 midi2_midi1_ep_in_class_desc = {
 +	.bLength =		0x05,
 +	.bDescriptorType =	USB_DT_CS_ENDPOINT,
 +	.bDescriptorSubtype =	USB_MS_GENERAL,
 +	.bNumEmbMIDIJack =	1,
 +	.baAssocJackID =	{ 0x03 },
 +};
 +
 +/* MIDI 2.0 Streaming Interface (altset 1) */
 +static struct usb_interface_descriptor midi2_midi2_if_desc = {
 +	.bLength =		USB_DT_INTERFACE_SIZE,
 +	.bDescriptorType =	USB_DT_INTERFACE,
 +	.bInterfaceNumber =	0, // to be filled
 +	.bAlternateSetting =	1,
 +	.bNumEndpoints =	2,
 +	.bInterfaceClass =	USB_CLASS_AUDIO,
 +	.bInterfaceSubClass =	USB_SUBCLASS_MIDISTREAMING,
 +	.bInterfaceProtocol =	0,
 +	.iInterface =		0, // to be filled
 +};
 +
 +static struct usb_ms_header_descriptor midi2_midi2_class_desc = {
 +	.bLength =		0x07,
 +	.bDescriptorType =	USB_DT_CS_INTERFACE,
 +	.bDescriptorSubtype =	USB_MS_HEADER,
 +	.bcdMSC =		__cpu_to_le16(0x0200),
 +	.wTotalLength =		__cpu_to_le16(0x07),
 +};
 +
 +/* MIDI 2.0 EP OUT */
 +static struct usb_endpoint_descriptor midi2_midi2_ep_out_desc[MAX_UMP_EPS];
 +
 +static struct usb_ss_ep_comp_descriptor midi2_midi2_ep_out_ss_comp_desc = {
 +	.bLength                = sizeof(midi2_midi1_ep_out_ss_comp_desc),
 +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
 +};
 +
 +static struct usb_ms20_endpoint_descriptor_32 midi2_midi2_ep_out_class_desc[MAX_UMP_EPS];
 +
 +/* MIDI 2.0 EP IN */
 +static struct usb_endpoint_descriptor midi2_midi2_ep_in_desc[MAX_UMP_EPS];
 +
 +static struct usb_ss_ep_comp_descriptor midi2_midi2_ep_in_ss_comp_desc = {
 +	.bLength                = sizeof(midi2_midi2_ep_in_ss_comp_desc),
 +	.bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
 +};
 +
 +static struct usb_ms20_endpoint_descriptor_32 midi2_midi2_ep_in_class_desc[MAX_UMP_EPS];
 +
 +/* Arrays of descriptors to be created */
 +static void *midi2_audio_descs[] = {
 +	&midi2_audio_if_desc,
 +	&midi2_audio_class_desc,
 +	NULL
 +};
 +
 +static void *midi2_midi1_descs[] = {
 +	&midi2_midi1_if_desc,
 +	&midi2_midi1_class_desc,
 +	&midi2_midi1_in_jack1_desc,
 +	&midi2_midi1_in_jack2_desc,
 +	&midi2_midi1_out_jack1_desc,
 +	&midi2_midi1_out_jack2_desc,
 +	NULL
 +};
 +
 +static void *midi2_midi1_ep_descs[] = {
 +	&midi2_midi1_ep_out_desc,
 +	&midi2_midi1_ep_out_class_desc,
 +	&midi2_midi1_ep_in_desc,
 +	&midi2_midi1_ep_in_class_desc,
 +	NULL
 +};
 +
 +static void *midi2_midi1_ep_ss_descs[] = {
 +	&midi2_midi1_ep_out_desc,
 +	&midi2_midi1_ep_out_ss_comp_desc,
 +	&midi2_midi1_ep_out_class_desc,
 +	&midi2_midi1_ep_in_desc,
 +	&midi2_midi1_ep_in_ss_comp_desc,
 +	&midi2_midi1_ep_in_class_desc,
 +	NULL
 +};
 +
 +static void *midi2_midi2_descs[] = {
 +	&midi2_midi2_if_desc,
 +	&midi2_midi2_class_desc,
 +	NULL
 +};
 +
 +/*
 + * USB request handling
 + */
 +
 +/* get an empty request for the given EP */
 +static struct usb_request *get_empty_request(struct f_midi2_usb_ep *usb_ep)
 +{
 +	struct usb_request *req = NULL;
 +	unsigned long flags;
 +	int index;
 +
 +	spin_lock_irqsave(&usb_ep->card->queue_lock, flags);
 +	if (!usb_ep->free_reqs)
 +		goto unlock;
 +	index = find_first_bit(&usb_ep->free_reqs, usb_ep->num_reqs);
 +	if (index >= usb_ep->num_reqs)
 +		goto unlock;
 +	req = usb_ep->reqs[index].req;
 +	if (!req)
 +		goto unlock;
 +	clear_bit(index, &usb_ep->free_reqs);
 +	req->length = 0;
 + unlock:
 +	spin_unlock_irqrestore(&usb_ep->card->queue_lock, flags);
 +	return req;
 +}
 +
 +/* put the empty request back */
 +static void put_empty_request(struct usb_request *req)
 +{
 +	struct f_midi2_req_ctx *ctx = req->context;
 +	unsigned long flags;
 +
 +	spin_lock_irqsave(&ctx->usb_ep->card->queue_lock, flags);
 +	set_bit(ctx->index, &ctx->usb_ep->free_reqs);
 +	spin_unlock_irqrestore(&ctx->usb_ep->card->queue_lock, flags);
 +}
 +
 +/*
 + * UMP v1.1 Stream message handling
 + */
 +
 +/* queue a request to UMP EP; request is either queued or freed after this */
 +static int queue_request_ep_raw(struct usb_request *req)
 +{
 +	struct f_midi2_req_ctx *ctx = req->context;
 +	int err;
 +
 +	req->complete = ctx->usb_ep->complete;
 +	err = usb_ep_queue(ctx->usb_ep->usb_ep, req, GFP_ATOMIC);
 +	if (err) {
 +		put_empty_request(req);
 +		return err;
 +	}
 +	return 0;
 +}
 +
 +/* queue a request with endianness conversion */
 +static int queue_request_ep_in(struct usb_request *req)
 +{
 +	/* UMP packets have to be converted to little-endian */
 +	cpu_to_le32_array((u32 *)req->buf, req->length >> 2);
 +	return queue_request_ep_raw(req);
 +}
 +
 +/* reply a UMP packet via EP-in */
 +static int reply_ep_in(struct f_midi2_ep *ep, const void *buf, int len)
 +{
 +	struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
 +	struct usb_request *req;
 +
 +	req = get_empty_request(usb_ep);
 +	if (!req)
 +		return -ENOSPC;
 +
 +	req->length = len;
 +	memcpy(req->buf, buf, len);
 +	return queue_request_ep_in(req);
 +}
 +
 +/* reply a UMP stream EP info */
 +static void reply_ump_stream_ep_info(struct f_midi2_ep *ep)
 +{
 +	struct snd_ump_stream_msg_ep_info rep = {
 +		.type = UMP_MSG_TYPE_STREAM,
 +		.status = UMP_STREAM_MSG_STATUS_EP_INFO,
 +		.ump_version_major = 0x01,
 +		.ump_version_minor = 0x01,
 +		.num_function_blocks = ep->num_blks,
 +		.static_function_block = !!ep->card->info.static_block,
 +		.protocol = (UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 |
 +			     UMP_STREAM_MSG_EP_INFO_CAP_MIDI2) >> 8,
 +	};
 +
 +	reply_ep_in(ep, &rep, sizeof(rep));
 +}
 +
 +/* reply a UMP EP device info */
 +static void reply_ump_stream_ep_device(struct f_midi2_ep *ep)
 +{
 +	struct snd_ump_stream_msg_devince_info rep = {
 +		.type = UMP_MSG_TYPE_STREAM,
 +		.status = UMP_STREAM_MSG_STATUS_DEVICE_INFO,
 +		.manufacture_id = ep->info.manufacturer,
 +		.family_lsb = ep->info.family & 0xff,
 +		.family_msb = (ep->info.family >> 8) & 0xff,
 +		.model_lsb = ep->info.model & 0xff,
 +		.model_msb = (ep->info.model >> 8) & 0xff,
 +		.sw_revision = ep->info.sw_revision,
 +	};
 +
 +	reply_ep_in(ep, &rep, sizeof(rep));
 +}
 +
 +#define UMP_STREAM_PKT_BYTES	16	/* UMP stream packet size = 16 bytes*/
 +#define UMP_STREAM_EP_STR_OFF	2	/* offset of name string for EP info */
 +#define UMP_STREAM_FB_STR_OFF	3	/* offset of name string for FB info */
 +
 +/* Helper to replay a string */
 +static void reply_ump_stream_string(struct f_midi2_ep *ep, const u8 *name,
 +				    unsigned int type, unsigned int extra,
 +				    unsigned int start_ofs)
 +{
 +	struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
 +	struct f_midi2 *midi2 = ep->card;
 +	struct usb_request *req;
 +	unsigned int pos;
 +	u32 *buf;
 +
 +	if (!*name)
 +		return;
 +	req = get_empty_request(usb_ep);
 +	if (!req)
 +		return;
 +
 +	buf = (u32 *)req->buf;
 +	pos = start_ofs;
 +	for (;;) {
 +		if (pos == start_ofs) {
 +			memset(buf, 0, UMP_STREAM_PKT_BYTES);
 +			buf[0] = ump_stream_compose(type, 0) | extra;
 +		}
 +		buf[pos / 4] |= *name++ << ((3 - (pos % 4)) * 8);
 +		if (!*name) {
 +			if (req->length)
 +				buf[0] |= UMP_STREAM_MSG_FORMAT_END << 26;
 +			req->length += UMP_STREAM_PKT_BYTES;
 +			break;
 +		}
 +		if (++pos == UMP_STREAM_PKT_BYTES) {
 +			if (!req->length)
 +				buf[0] |= UMP_STREAM_MSG_FORMAT_START << 26;
 +			else
 +				buf[0] |= UMP_STREAM_MSG_FORMAT_CONTINUE << 26;
 +			req->length += UMP_STREAM_PKT_BYTES;
 +			if (midi2->info.req_buf_size - req->length < UMP_STREAM_PKT_BYTES)
 +				break;
 +			buf += 4;
 +			pos = start_ofs;
 +		}
 +	}
 +
 +	if (req->length)
 +		queue_request_ep_in(req);
 +	else
 +		put_empty_request(req);
 +}
 +
 +/* Reply a UMP EP name string */
 +static void reply_ump_stream_ep_name(struct f_midi2_ep *ep)
 +{
 +	reply_ump_stream_string(ep, ump_ep_name(ep),
 +				UMP_STREAM_MSG_STATUS_EP_NAME, 0,
 +				UMP_STREAM_EP_STR_OFF);
 +}
 +
 +/* Reply a UMP EP product ID string */
 +static void reply_ump_stream_ep_pid(struct f_midi2_ep *ep)
 +{
 +	reply_ump_stream_string(ep, ump_product_id(ep),
 +				UMP_STREAM_MSG_STATUS_PRODUCT_ID, 0,
 +				UMP_STREAM_EP_STR_OFF);
 +}
 +
 +/* Reply a UMP EP stream config */
 +static void reply_ump_stream_ep_config(struct f_midi2_ep *ep)
 +{
 +	struct snd_ump_stream_msg_stream_cfg rep = {
 +		.type = UMP_MSG_TYPE_STREAM,
 +		.status = UMP_STREAM_MSG_STATUS_STREAM_CFG,
 +	};
 +
 +	if ((ep->info.protocol & SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK) ==
 +	    SNDRV_UMP_EP_INFO_PROTO_MIDI2)
 +		rep.protocol = UMP_STREAM_MSG_EP_INFO_CAP_MIDI2 >> 8;
 +	else
 +		rep.protocol = UMP_STREAM_MSG_EP_INFO_CAP_MIDI1 >> 8;
 +
 +	reply_ep_in(ep, &rep, sizeof(rep));
 +}
 +
 +/* Reply a UMP FB info */
 +static void reply_ump_stream_fb_info(struct f_midi2_ep *ep, int blk)
 +{
 +	struct f_midi2_block_info *b = &ep->blks[blk].info;
 +	struct snd_ump_stream_msg_fb_info rep = {
 +		.type = UMP_MSG_TYPE_STREAM,
 +		.status = UMP_STREAM_MSG_STATUS_FB_INFO,
 +		.active = !!b->active,
 +		.function_block_id = blk,
 +		.ui_hint = b->ui_hint,
 +		.midi_10 = b->is_midi1,
 +		.direction = b->direction,
 +		.first_group = b->first_group,
 +		.num_groups = b->num_groups,
 +		.midi_ci_version = b->midi_ci_version,
 +		.sysex8_streams = b->sysex8_streams,
 +	};
 +
 +	reply_ep_in(ep, &rep, sizeof(rep));
 +}
 +
 +/* Reply a FB name string */
 +static void reply_ump_stream_fb_name(struct f_midi2_ep *ep, unsigned int blk)
 +{
 +	reply_ump_stream_string(ep, ump_fb_name(&ep->blks[blk].info),
 +				UMP_STREAM_MSG_STATUS_FB_NAME, blk << 8,
 +				UMP_STREAM_FB_STR_OFF);
 +}
 +
 +/* Process a UMP Stream message */
 +static void process_ump_stream_msg(struct f_midi2_ep *ep, const u32 *data)
 +{
 +	struct f_midi2 *midi2 = ep->card;
 +	unsigned int format, status, blk;
 +
 +	format = ump_stream_message_format(*data);
 +	status = ump_stream_message_status(*data);
 +	switch (status) {
 +	case UMP_STREAM_MSG_STATUS_EP_DISCOVERY:
 +		if (format)
 +			return; // invalid
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_EP_INFO)
 +			reply_ump_stream_ep_info(ep);
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_DEVICE_INFO)
 +			reply_ump_stream_ep_device(ep);
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_EP_NAME)
 +			reply_ump_stream_ep_name(ep);
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_PRODUCT_ID)
 +			reply_ump_stream_ep_pid(ep);
 +		if (data[1] & UMP_STREAM_MSG_REQUEST_STREAM_CFG)
 +			reply_ump_stream_ep_config(ep);
 +		return;
 +	case UMP_STREAM_MSG_STATUS_STREAM_CFG_REQUEST:
 +		if (*data & UMP_STREAM_MSG_EP_INFO_CAP_MIDI2) {
 +			ep->info.protocol = SNDRV_UMP_EP_INFO_PROTO_MIDI2;
 +			DBG(midi2, "Switching Protocol to MIDI2\n");
 +		} else {
 +			ep->info.protocol = SNDRV_UMP_EP_INFO_PROTO_MIDI1;
 +			DBG(midi2, "Switching Protocol to MIDI1\n");
 +		}
 +		snd_ump_switch_protocol(ep->ump, ep->info.protocol);
 +		reply_ump_stream_ep_config(ep);
 +		return;
 +	case UMP_STREAM_MSG_STATUS_FB_DISCOVERY:
 +		if (format)
 +			return; // invalid
 +		blk = (*data >> 8) & 0xff;
 +		if (blk >= ep->num_blks)
 +			return;
 +		if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO)
 +			reply_ump_stream_fb_info(ep, blk);
 +		if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME)
 +			reply_ump_stream_fb_name(ep, blk);
 +		return;
 +	}
 +}
 +
 +/* Process UMP messages included in a USB request */
 +static void process_ump(struct f_midi2_ep *ep, const struct usb_request *req)
 +{
 +	const u32 *data = (u32 *)req->buf;
 +	int len = req->actual >> 2;
 +	const u32 *in_buf = ep->ump->input_buf;
 +
 +	for (; len > 0; len--, data++) {
 +		if (snd_ump_receive_ump_val(ep->ump, *data) <= 0)
 +			continue;
 +		if (ump_message_type(*in_buf) == UMP_MSG_TYPE_STREAM)
 +			process_ump_stream_msg(ep, in_buf);
 +	}
 +}
 +
 +/*
 + * MIDI 2.0 UMP USB request handling
 + */
 +
 +/* complete handler for UMP EP-out requests */
 +static void f_midi2_ep_out_complete(struct usb_ep *usb_ep,
 +				    struct usb_request *req)
 +{
 +	struct f_midi2_req_ctx *ctx = req->context;
 +	struct f_midi2_ep *ep = ctx->usb_ep->ep;
 +	struct f_midi2 *midi2 = ep->card;
 +	int status = req->status;
 +
 +	if (status) {
 +		DBG(midi2, "%s complete error %d: %d/%d\n",
 +		    usb_ep->name, status, req->actual, req->length);
 +		goto error;
 +	}
 +
 +	/* convert to UMP packet in native endianness */
 +	le32_to_cpu_array((u32 *)req->buf, req->actual >> 2);
 +
 +	if (midi2->info.process_ump)
 +		process_ump(ep, req);
 +
 +	snd_ump_receive(ep->ump, req->buf, req->actual & ~3);
 +
 +	if (midi2->operation_mode != MIDI_OP_MODE_MIDI2)
 +		goto error;
 +
 +	if (queue_request_ep_raw(req))
 +		goto error;
 +	return;
 +
 + error:
 +	put_empty_request(req);
 +}
 +
 +/* Transmit UMP packets received from user-space to the gadget */
 +static void process_ump_transmit(struct f_midi2_ep *ep)
 +{
 +	struct f_midi2_usb_ep *usb_ep = &ep->ep_in;
 +	struct f_midi2 *midi2 = ep->card;
 +	struct usb_request *req;
 +	int len;
 +
 +	if (!usb_ep->usb_ep->enabled)
 +		return;
 +
 +	for (;;) {
 +		req = get_empty_request(usb_ep);
 +		if (!req)
 +			break;
 +		len = snd_ump_transmit(ep->ump, (u32 *)req->buf,
 +				       midi2->info.req_buf_size);
 +		if (len <= 0) {
 +			put_empty_request(req);
 +			break;
 +		}
 +
 +		req->length = len;
 +		if (queue_request_ep_in(req) < 0)
 +			break;
 +	}
 +}
 +
 +/* Complete handler for UMP EP-in requests */
 +static void f_midi2_ep_in_complete(struct usb_ep *usb_ep,
 +				   struct usb_request *req)
 +{
 +	struct f_midi2_req_ctx *ctx = req->context;
 +	struct f_midi2_ep *ep = ctx->usb_ep->ep;
 +	struct f_midi2 *midi2 = ep->card;
 +	int status = req->status;
 +
 +	put_empty_request(req);
 +
 +	if (status) {
 +		DBG(midi2, "%s complete error %d: %d/%d\n",
 +		    usb_ep->name, status, req->actual, req->length);
 +		return;
 +	}
 +
 +	process_ump_transmit(ep);
 +}
 +
 +/* Start MIDI EP */
 +static int f_midi2_start_ep(struct f_midi2_usb_ep *usb_ep,
 +			    struct usb_function *fn)
 +{
 +	int err;
 +
 +	usb_ep_disable(usb_ep->usb_ep);
 +	err = config_ep_by_speed(usb_ep->card->gadget, fn, usb_ep->usb_ep);
 +	if (err)
 +		return err;
 +	return usb_ep_enable(usb_ep->usb_ep);
 +}
 +
 +/* Drop pending requests */
 +static void f_midi2_drop_reqs(struct f_midi2_usb_ep *usb_ep)
 +{
 +	int i;
 +
 +	if (!usb_ep->num_reqs)
 +		return;
 +
 +	for (i = 0; i < usb_ep->num_reqs; i++) {
 +		if (!test_bit(i, &usb_ep->free_reqs) && usb_ep->reqs[i].req) {
 +			usb_ep_dequeue(usb_ep->usb_ep, usb_ep->reqs[i].req);
 +			set_bit(i, &usb_ep->free_reqs);
 +		}
 +	}
 +}
 +
 +/* Allocate requests for the given EP */
 +static int f_midi2_alloc_ep_reqs(struct f_midi2_usb_ep *usb_ep)
 +{
 +	struct f_midi2 *midi2 = usb_ep->card;
 +	int i;
 +
 +	if (!usb_ep->reqs)
 +		return -EINVAL;
 +
 +	for (i = 0; i < midi2->info.num_reqs; i++) {
 +		if (usb_ep->reqs[i].req)
 +			continue;
 +		usb_ep->reqs[i].req = alloc_ep_req(usb_ep->usb_ep,
 +						   midi2->info.req_buf_size);
 +		if (!usb_ep->reqs[i].req)
 +			return -ENOMEM;
 +		usb_ep->reqs[i].req->context = &usb_ep->reqs[i];
 +	}
 +	return 0;
 +}
 +
 +/* Free allocated requests */
 +static void f_midi2_free_ep_reqs(struct f_midi2_usb_ep *usb_ep)
 +{
 +	struct f_midi2 *midi2 = usb_ep->card;
 +	int i;
 +
 +	for (i = 0; i < midi2->info.num_reqs; i++) {
 +		if (!usb_ep->reqs[i].req)
 +			continue;
 +		free_ep_req(usb_ep->usb_ep, usb_ep->reqs[i].req);
 +		usb_ep->reqs[i].req = NULL;
 +	}
 +}
 +
 +/* Initialize EP */
 +static int f_midi2_init_ep(struct f_midi2 *midi2, struct f_midi2_ep *ep,
 +			   struct f_midi2_usb_ep *usb_ep,
 +			   void *desc, int num_reqs,
 +			   void (*complete)(struct usb_ep *usb_ep,
 +					    struct usb_request *req))
 +{
 +	int i;
 +
 +	usb_ep->card = midi2;
 +	usb_ep->ep = ep;
 +	usb_ep->usb_ep = usb_ep_autoconfig(midi2->gadget, desc);
 +	if (!usb_ep->usb_ep)
 +		return -ENODEV;
 +	usb_ep->complete = complete;
 +
 +	if (num_reqs) {
 +		usb_ep->reqs = kcalloc(num_reqs, sizeof(*usb_ep->reqs),
 +				       GFP_KERNEL);
 +		if (!usb_ep->reqs)
 +			return -ENOMEM;
 +		for (i = 0; i < num_reqs; i++) {
 +			usb_ep->reqs[i].index = i;
 +			usb_ep->reqs[i].usb_ep = usb_ep;
 +			set_bit(i, &usb_ep->free_reqs);
 +			usb_ep->num_reqs++;
 +		}
 +	}
 +
 +	return 0;
 +}
 +
 +/* Free EP */
 +static void f_midi2_free_ep(struct f_midi2_usb_ep *usb_ep)
 +{
 +	f_midi2_drop_reqs(usb_ep);
 +
 +	f_midi2_free_ep_reqs(usb_ep);
 +
 +	kfree(usb_ep->reqs);
 +	usb_ep->num_reqs = 0;
 +	usb_ep->free_reqs = 0;
 +	usb_ep->reqs = NULL;
 +}
 +
 +/* Queue requests for EP-out at start */
 +static void f_midi2_queue_out_reqs(struct f_midi2_usb_ep *usb_ep)
 +{
 +	int i, err;
 +
 +	for (i = 0; i < usb_ep->num_reqs; i++) {
 +		if (!test_bit(i, &usb_ep->free_reqs) || !usb_ep->reqs[i].req)
 +			continue;
 +		usb_ep->reqs[i].req->complete = usb_ep->complete;
 +		err = usb_ep_queue(usb_ep->usb_ep, usb_ep->reqs[i].req,
 +				   GFP_ATOMIC);
 +		if (!err)
 +			clear_bit(i, &usb_ep->free_reqs);
 +	}
 +}
 +
 +/*
 + * Gadget Function callbacks
 + */
 +
 +/* gadget function set_alt callback */
 +static int f_midi2_set_alt(struct usb_function *fn, unsigned int intf,
 +			   unsigned int alt)
 +{
 +	struct f_midi2 *midi2 = func_to_midi2(fn);
 +	struct f_midi2_ep *ep;
 +	int i, op_mode, err;
 +
 +	if (intf != midi2->midi_if || alt > 1)
 +		return 0;
 +
 +	if (alt == 0)
 +		op_mode = MIDI_OP_MODE_MIDI1;
 +	else if (alt == 1)
 +		op_mode = MIDI_OP_MODE_MIDI2;
 +	else
 +		op_mode = MIDI_OP_MODE_UNSET;
 +
 +	if (midi2->operation_mode == op_mode)
 +		return 0;
 +
]
]

394/2 2026/07/30 15:11 llm fixes-finder
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 52254
							output: 49
							thoughts: 2044
						

Thoughts:
**Analysis of MIDI2 ConfigFS Initialization and Cleanup**

Okay, so it looks like the `f_midi2_ep_opts_release` function wasn't present in the initial commit `8b645922b22303cec4628dbbbf6c8553d1cdec87`, and I needed to verify this for my investigation. I just confirmed that this commit didn't include the function.

Now, looking at the diffs, I can see that in commit `8b645922b22303cec4628dbbbf6c8553d1cdec87`, `f_midi2_alloc_inst` and `f_midi2_free_inst` were pretty straightforward, allocating and freeing the endpoint and block structures directly without configfs. They were simple allocations and frees for the single endpoint and feedback block. However, there were NO configfs default groups (`ep.0` and `block.0`).

Then, the introduction of the configfs default groups happened in `29ee7a4dddd5caa18d1cef000f20c6af43f762f1`. This patch added the calls to `configfs_add_default_group` within `f_midi2_alloc_inst` for the `ep.0` and `block.0` groups. At the same time, `f_midi2_ep_opts_release` was also introduced to free endpoint specific resources. Furthermore, the `f_midi2_free_inst` function had its ep and block cleanup logic removed as a direct result of these ConfigFS changes.

Here's the problem: The original commit, `29ee7a4dddd5caa18d1cef000f20c6af43f762f1`, added the configuration logic but *did not* include the corresponding `configfs_remove_default_groups` calls in the release functions (`f_midi2_ep_opts_release` and `f_midi2_free_inst`). That means the configfs groups were created but not correctly removed.

Given this, a separate patch (which I don't have here) should, and will have to, add the missing `configfs_remove_default_groups` calls to the `f_midi2_ep_opts_release` and `f_midi2_free_inst` functions. This is precisely what's needed to fix the resource leak caused by the incomplete configfs integration in the `29ee7a4dddd5caa18d1cef000f20c6af43f762f1` commit. I just confirmed this to be the case based on the changes to those functions and the fact that `29ee7a4dddd5caa18d1cef000f20c6af43f762f1` is indeed the commit hash introducing the problematic code.



395/2 2026/07/30 15:11 tool set-results
0m Args:
map[FixesHash:29ee7a4dddd5caa18d1cef000f20c6af43f762f1]

Results:
map[FixesHash:29ee7a4dddd5caa18d1cef000f20c6af43f762f1]

396/1 2026/07/30 15:11 action format-fixes
0m Results:
map[Fixes:map[AuthorEmail:tiwai@suse.de AuthorName:Takashi Iwai Hash:29ee7a4dddd5caa18d1cef000f20c6af43f762f1 Title:usb: gadget: midi2: Add configfs support]]

397/1 2026/07/30 15:11 action get-maintainers
0m Results:
map[Recipients:[map[Email:christophe.jaillet@wanadoo.fr Name:Christophe JAILLET To:false] map[Email:gregkh@linuxfoundation.org Name:Greg Kroah-Hartman To:true] map[Email:kees@kernel.org Name:Kees Cook To:false] map[Email:linux-kernel@vger.kernel.org Name: To:false] map[Email:linux-usb@vger.kernel.org Name: To:true] map[Email:tiwai@suse.de Name:Takashi Iwai To:true]]]

398/1 2026/07/30 15:11 action get-recent-commits
0m Results:
map[RecentCommits:usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
Convert more 'alloc_obj' cases to default GFP_KERNEL arguments
Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
treewide: Replace kmalloc with kmalloc_obj for non-scalar types
usb: gadget: Constify struct configfs_item_operations and configfs_group_operations
usb: gadget: midi2: Fix MIDI2 IN EP max packet size
usb: gadget: midi2: Fix missing UMP group attributes initialization
ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info
usb: gadget: midi2: Fix interpretation of is_midi1 bits
usb: gadget: function: remove redundant else statement
usb: gadget: function: move u_f.h to include/linux/usb/func_utils.h
usb: gadget: midi2: Fix the response for FB info with block 0xff
usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
usb: gadget: add missing MODULE_DESCRIPTION() macros
usb: gadget: unconditionally allocate hs/ss descriptor in bind operation
usb: gadget: midi2: fix missing unlock in f_midi2_block_opts_create()
usb: gadget: midi2: More flexible MIDI 1.0 configuration
usb: gadget: midi2: Add "Operation Mode" control
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support
]

399/1 2026/07/30 15:11 agent description-generator
0m Model:
best-expensive

Instruction:
You are an experienced Linux kernel developer tasked with writing a commit description for
a kernel bug fixing commit. The description should start with a one-line summary,
and then include description of the bug being fixed, and how it's fixed by the provided patch.
The one-line summary should describe the change being made, rather than mention the tool that
detected the bug.

The description must not contain lines starting with '#' because they will dropped by git as comments.
The description must not contain lines starting with '--' or '---' (including inline code diffs)
because they may confuse git/patch utilities.

Your final reply should contain only the text of the commit description.


The one-line summary must be not longer than 72 characters.

IMPORTANT: Do not wrap lines manually (e.g., at 80 characters); we will reformat the text
automatically, so keep paragraphs as single lines without newlines.

Generally try to phrase the description without mentioning syzkaller
(avoid phrases like "the bug was triggered by syzkaller" or "the bug was triggered by fuzzer", etc).
How the bug was triggered is generally an irrelevant detail.
Any bug triggered by a fuzzer can also be triggered by a malicious user, or a buggy program.

If the crash is reported by a sanitizer (e.g., KASAN, KMSAN, lockdep), include the relevant
parts of the sanitizer output to illustrate the problem. Exclude less relevant sections,
as the stack trace can be very long. Describe the execution path that leads to the manifestation
of the kernel bug.



Prefer calling several tools at the same time to save round-trips.

Prompt:
The crash that corresponds to the bug is:

2026/07/30 13:30:35 executed programs: 5
BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504 [inline]
    f_midi2_alloc_inst+0x80/0x2c0 drivers/usb/gadget/function/f_midi2.c:2666
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
    slab_post_alloc_hook mm/slub.c:4597 [inline]
    slab_alloc_node mm/slub.c:4917 [inline]
    __kmalloc_cache_noprof+0x1be/0x3f0 mm/slub.c:5485
    _kmalloc_noprof include/linux/slab.h:988 [inline]
    _kzalloc_noprof include/linux/slab.h:1309 [inline]
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342 [inline]
    f_midi2_alloc_inst+0x16a/0x2c0 drivers/usb/gadget/function/f_midi2.c:2673
    try_get_usb_function_instance drivers/usb/gadget/functions.c:28 [inline]
    usb_get_function_instance+0x6f/0x1c0 drivers/usb/gadget/functions.c:44
    function_make+0xcf/0x210 drivers/usb/gadget/configfs.c:626
    configfs_mkdir+0x26e/0x540 fs/configfs/dir.c:1360
    vfs_mkdir+0x204/0x320 fs/namei.c:5276
    filename_mkdirat+0x14e/0x2e0 fs/namei.c:5309
    __do_sys_mkdirat fs/namei.c:5330 [inline]
    __se_sys_mkdirat+0x30/0xd0 fs/namei.c:5327
    do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
    do_syscall_64+0x14f/0x3c0 arch/x86/entry/syscall_64.c:94
    entry_SYSCALL_64_after_hwframe+0x77/0x7f

connection error: failed to recv *flatrpc.ExecutorMessageRawT: EOF




The explanation of the root cause of the bug is:

The root cause of this memory leak is that the driver fails to drop the reference counts of its default configfs groups when the parent group is destroyed.

When a USB function instance for `midi2` is allocated via `f_midi2_alloc_inst()`, it dynamically allocates `ep_opts` and `block_opts` structures using `kzalloc_obj()`. These structures are then initialized as configfs groups and added as default groups to their respective parents:
- `ep.0` is added as a default group to the function instance group (`opts->func_inst.group`).
- `block.0` is added as a default group to the endpoint group (`ep_opts->group`).

When the user removes the configfs directory for the function instance (via `rmdir`), configfs removes the dentries for the default groups but **does not** automatically drop their reference counts. The responsibility of dropping the refcounts of default groups lies with the driver, typically by calling `configfs_remove_default_groups()` when the parent group is released.

However, `f_midi2_free_inst()` (which is called when the function instance's refcount reaches 0) only frees the `f_midi2_opts` structure and does not clean up its default groups. Similarly, `f_midi2_ep_opts_release()` does not clean up its default groups. As a result, the `ep_opts` and `block_opts` structures are leaked.

### How to fix it

To fix the leak, you need to explicitly remove the default groups and drop their reference counts before freeing the parent structures. This can be done by calling `configfs_remove_default_groups()` in the respective release functions.

1. In `f_midi2_free_inst()`, drop the default groups of the function instance (this will drop the refcount of `ep.0` and trigger `f_midi2_ep_opts_release`):
```c
static void f_midi2_free_inst(struct usb_function_instance *f)
{
	struct f_midi2_opts *opts;

	opts = container_of(f, struct f_midi2_opts, func_inst);

	configfs_remove_default_groups(&opts->func_inst.group); /* ADD THIS */
	kfree(opts->info.iface_name);
	kfree(opts);
}
```

2. In `f_midi2_ep_opts_release()`, drop the default groups of the endpoint (this will drop the refcount of `block.0` and trigger `f_midi2_block_opts_release`):
```c
static void f_midi2_ep_opts_release(struct config_item *item)
{
	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);

	configfs_remove_default_groups(to_config_group(item)); /* ADD THIS */
	kfree(opts->info.ep_name);
	kfree(opts->info.product_id);
	kfree(opts);
}
```

With these changes, the hierarchy of default groups will be properly unrolled and freed when the function instance is destroyed, whether it's through configfs `rmdir` or an error path that directly calls `usb_put_function_instance()`.

The diff of the bug fix is:

diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c
index 19fdac024..ec4266ecc 100644
--- a/drivers/usb/gadget/function/f_midi2.c
+++ b/drivers/usb/gadget/function/f_midi2.c
@@ -2473,6 +2473,7 @@ static void f_midi2_ep_opts_release(struct config_item *item)
 {
 	struct f_midi2_ep_opts *opts = to_f_midi2_ep_opts(item);
 
+	configfs_remove_default_groups(to_config_group(item));
 	kfree(opts->info.ep_name);
 	kfree(opts->info.product_id);
 	kfree(opts);
@@ -2639,6 +2640,7 @@ static void f_midi2_free_inst(struct usb_function_instance *f)
 
 	opts = container_of(f, struct f_midi2_opts, func_inst);
 
+	configfs_remove_default_groups(&opts->func_inst.group);
 	kfree(opts->info.iface_name);
 	kfree(opts);
 }


Additional description of the patch:

I have implemented the fix for the memory leak in the `f_midi2` USB gadget function driver.

### What I did
I added calls to `configfs_remove_default_groups()` in the release functions of the configfs groups that have default groups attached to them:
1. In `f_midi2_free_inst()`, I added `configfs_remove_default_groups(&opts->func_inst.group);` to drop the reference count of the default `ep.0` group.
2. In `f_midi2_ep_opts_release()`, I added `configfs_remove_default_groups(to_config_group(item));` to drop the reference count of the default `block.0` group.

### Why I did it
When a USB function instance for `midi2` is allocated, it dynamically allocates `ep_opts` and `block_opts` structures and adds them as default groups (`ep.0` and `block.0`). While configfs removes the dentries for default groups when the parent directory is removed, it does not automatically drop their reference counts. This responsibility lies with the driver.

By explicitly calling `configfs_remove_default_groups()` in the respective release functions, we ensure that the reference counts of the default groups are properly dropped. This correctly triggers the existing release callbacks (`f_midi2_ep_opts_release` and `f_midi2_block_opts_release`), which safely free the dynamically allocated memory in the correct order.

This approach is robust and idiomatic. It also safely handles dynamically created groups (e.g., `ep.1` created via `mkdir`), because their `default_groups` list is properly initialized and empty, making `configfs_remove_default_groups()` a safe no-op for them.

Here are summaries of recent commits that touched the same files.
Format the summary line consistently with these, look how prefixes
are specified, letter capitalization, style, etc. 

usb: gadget: functionfs: Use safer strscpy() instead of strcpy()
Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses
Convert more 'alloc_obj' cases to default GFP_KERNEL arguments
Convert 'alloc_obj' family to use the new default GFP_KERNEL argument
treewide: Replace kmalloc with kmalloc_obj for non-scalar types
usb: gadget: Constify struct configfs_item_operations and configfs_group_operations
usb: gadget: midi2: Fix MIDI2 IN EP max packet size
usb: gadget: midi2: Fix missing UMP group attributes initialization
ALSA: ump: Fix a typo of snd_ump_stream_msg_device_info
usb: gadget: midi2: Fix interpretation of is_midi1 bits
usb: gadget: function: remove redundant else statement
usb: gadget: function: move u_f.h to include/linux/usb/func_utils.h
usb: gadget: midi2: Fix the response for FB info with block 0xff
usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
usb: gadget: add missing MODULE_DESCRIPTION() macros
usb: gadget: unconditionally allocate hs/ss descriptor in bind operation
usb: gadget: midi2: fix missing unlock in f_midi2_block_opts_create()
usb: gadget: midi2: More flexible MIDI 1.0 configuration
usb: gadget: midi2: Add "Operation Mode" control
usb: gadget: midi2: MIDI 1.0 interface (altset 0) support


Reply:
usb: gadget: midi2: Fix memory leak in configfs default groups

When a USB function instance for midi2 is allocated, it dynamically
allocates ep_opts and block_opts structures and adds them as default groups
(ep.0 and block.0). While configfs removes the dentries for default groups
when the parent directory is removed, it does not automatically drop their
reference counts. This responsibility lies with the driver.

Because f_midi2_free_inst() and f_midi2_ep_opts_release() do not clean up
their default groups, the ep_opts and block_opts structures are leaked when
the function instance is destroyed.

Fix this by explicitly calling configfs_remove_default_groups() in the
respective release functions. This ensures that the reference counts of the
default groups are properly dropped, triggering the existing release
callbacks (f_midi2_ep_opts_release and f_midi2_block_opts_release) to
safely free the dynamically allocated memory.

Kmemleak reports:

BUG: memory leak
unreferenced object 0xffff88810aacb200 (size 512):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 b2 ac 0a 81 88 ff ff 65 70 2e 30 00 00 00 00  ........ep.0....
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc f2efe6a4):
    ...
    f_midi2_ep_opts_create drivers/usb/gadget/function/f_midi2.c:2504
    [inline]
    f_midi2_alloc_inst+0x80/0x2c0
    drivers/usb/gadget/function/f_midi2.c:2666
    ...

BUG: memory leak
unreferenced object 0xffff8881083d9e00 (size 256):
  comm "syz.0.19", pid 6225, jiffies 4294944049
  hex dump (first 32 bytes):
    08 9e 3d 08 81 88 ff ff 62 6c 6f 63 6b 2e 30 00  ..=.....block.0.
    00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ................
  backtrace (crc cc37bc9e):
    ...
    f_midi2_block_opts_create drivers/usb/gadget/function/f_midi2.c:2342
    [inline]
    f_midi2_alloc_inst+0x16a/0x2c0
    drivers/usb/gadget/function/f_midi2.c:2673
    ...

400/2 2026/07/30 15:11 llm description-generator
0m Model:
gemini-3.1-pro-preview

Tokens:
							input: 7277
							output: 754
							thoughts: 1773
						

Thoughts:
**usb: gadget: midi2: Fix memory leak in configfs default groups**

Okay, so I've been digging into this MIDI2 USB gadget driver, and I think I've tracked down a pretty nasty memory leak. It seems the core of the problem lies within how we're handling the ConfigFS default groups.

When we allocate a USB function instance for MIDI2, the driver dynamically creates `ep_opts` and `block_opts` structures. It then adds these as default groups within ConfigFS, specifically named `ep.0` and `block.0`. Now, ConfigFS is pretty good at cleaning up the dentries for these default groups when their parent directory goes away. However, it *doesn't* automatically decrement the reference counts for those groups. That's our responsibility as the driver authors.

The problem is, `f_midi2_free_inst()` and `f_midi2_ep_opts_release()` were missing this crucial step. They weren't cleaning up their default groups properly. Because of this oversight, the `ep_opts` and `block_opts` structures were getting leaked every time a function instance was destroyed. They'd just sit there, unreferenced, consuming memory.

The fix, and it's a pretty straightforward one, involves explicitly calling `configfs_remove_default_groups()` in both `f_midi2_free_inst()` and `f_midi2_ep_opts_release()`. This ensures that the reference counts for those default groups are dropped when they should be. This in turn triggers the existing release callbacks we have in place – `f_midi2_ep_opts_release` and `f_midi2_block_opts_release` – to safely release the dynamically allocated memory. Problem solved!

I've got the kmemleak reports showing the evidence clearly: We're seeing "unreferenced object" reports for both `ep.0` and `block.0`, indicating the leak. The backtraces point directly to `f_midi2_ep_opts_create` and `f_midi2_block_opts_create` during instance allocation, just as suspected. Based on the related commits, I'm confident this resolves an ongoing issue.



LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)