€•KŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ/translations/zh_CN/hid/hid-bpf”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/zh_TW/hid/hid-bpf”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/it_IT/hid/hid-bpf”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/ja_JP/hid/hid-bpf”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/ko_KR/hid/hid-bpf”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/pt_BR/hid/hid-bpf”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ/translations/sp_SP/hid/hid-bpf”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)�”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…”�”}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³Œ9/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf.rst”h´KubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒHID-BPF”h]”hŒHID-BPF”…”�”}”(hhÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhhÊh²hh³hÇh´KubhŒ paragraph”“”)�”}”(hŒùHID is a standard protocol for input devices but some devices may require custom tweaks, traditionally done with a kernel driver fix. Using the eBPF capabilities instead speeds up development and adds new capabilities to the existing HID interfaces.”h]”hŒùHID is a standard protocol for input devices but some devices may require custom tweaks, traditionally done with a kernel driver fix. Using the eBPF capabilities instead speeds up development and adds new capabilities to the existing HID interfaces.”…”�”}”(hhßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KhhÊh²hubhŒtopic”“”)�”}”(hhh]”hŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hhh]”(hÞ)�”}”(hhh]”hŒ reference”“”)�”}”(hhh]”hŒWhen (and why) to use HID-BPF”…”�”}”(hjh²hh³Nh´Nubah}”(h]”Œid1”ah ]”h"]”h$]”h&]”Œrefid”Œwhen-and-why-to-use-hid-bpf”uh1hÿhhüubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhhùubhó)�”}”(hhh]”(hø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒDead zone of a joystick”…”�”}”(hj h²hh³Nh´Nubah}”(h]”Œid2”ah ]”h"]”h$]”h&]”Œrefid”Œdead-zone-of-a-joystick”uh1hÿhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒ!Simple fixup of report descriptor”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”Œid3”ah ]”h"]”h$]”h&]”Œrefid”Œ!simple-fixup-of-report-descriptor”uh1hÿhj?ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj<ubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒ0Add a new feature that requires a new kernel API”…”�”}”(hjdh²hh³Nh´Nubah}”(h]”Œid4”ah ]”h"]”h$]”h&]”Œrefid”Œ0add-a-new-feature-that-requires-a-new-kernel-api”uh1hÿhjaubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj^ubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒBMorph a device into something else and control that from userspace”…”�”}”(hj†h²hh³Nh´Nubah}”(h]”Œid5”ah ]”h"]”h$]”h&]”Œrefid”ŒBmorph-a-device-into-something-else-and-control-that-from-userspace”uh1hÿhjƒubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj€ubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒFirewall”…”�”}”(hj¨h²hh³Nh´Nubah}”(h]”Œid6”ah ]”h"]”h$]”h&]”Œrefid”Œfirewall”uh1hÿhj¥ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj¢ubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒTracing”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”Œid7”ah ]”h"]”h$]”h&]”Œrefid”Œtracing”uh1hÿhjÇubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjÄubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1hòhhùubeh}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhôubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒHigh-level view of HID-BPF”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”Œid8”ah ]”h"]”h$]”h&]”Œrefid”Œhigh-level-view-of-hid-bpf”uh1hÿhjõubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjòubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhôubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”(hŒIn-tree HID-BPF programs and ”…”�”}”(hjh²hh³Nh´NubhŒliteral”“”)�”}”(hŒ``udev-hid-bpf``”h]”hŒ udev-hid-bpf”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!h³Nh´Nhjubeh}”(h]”Œid9”ah ]”h"]”h$]”h&]”Œrefid”Œ)in-tree-hid-bpf-programs-and-udev-hid-bpf”uh1hÿhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhôubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒAvailable types of programs”…”�”}”(hjLh²hh³Nh´Nubah}”(h]”Œid10”ah ]”h"]”h$]”h&]”Œrefid”Œavailable-types-of-programs”uh1hÿhjIubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjFubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhôubhø)�”}”(hhh]”(hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒDeveloper API:”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”Œid11”ah ]”h"]”h$]”h&]”Œrefid”Œ developer-api”uh1hÿhjkubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjhubhó)�”}”(hhh]”(hø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”(hŒ Available ”…”�”}”(hj�h²hh³Nh´Nubj")�”}”(hŒ``struct_ops``”h]”hŒ struct_ops”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!h³Nh´Nhj�ubhŒ for HID-BPF:”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”Œid12”ah ]”h"]”h$]”h&]”Œrefid”Œ available-struct-ops-for-hid-bpf”uh1hÿhjŠubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj‡ubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj„ubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒ/User API data structures available in programs:”…”�”}”(hjÁh²hh³Nh´Nubah}”(h]”Œid13”ah ]”h"]”h$]”h&]”Œrefid”Œ.user-api-data-structures-available-in-programs”uh1hÿhj¾ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj»ubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj„ubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒBAvailable API that can be used in all HID-BPF struct_ops programs:”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”Œid14”ah ]”h"]”h$]”h&]”Œrefid”ŒAavailable-api-that-can-be-used-in-all-hid-bpf-struct-ops-programs”uh1hÿhjàubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj„ubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒgAvailable API that can be used in syscall HID-BPF programs or in sleepable HID-BPF struct_ops programs:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”Œid15”ah ]”h"]”h$]”h&]”Œrefid”Œfavailable-api-that-can-be-used-in-syscall-hid-bpf-programs-or-in-sleepable-hid-bpf-struct-ops-programs”uh1hÿhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjÿubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj„ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hòhjhubeh}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhôubhø)�”}”(hhh]”(hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒ%General overview of a HID-BPF program”…”�”}”(hj3h²hh³Nh´Nubah}”(h]”Œid16”ah ]”h"]”h$]”h&]”Œrefid”Œ%general-overview-of-a-hid-bpf-program”uh1hÿhj0ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj-ubhó)�”}”(hhh]”(hø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒ*Accessing the data attached to the context”…”�”}”(hjRh²hh³Nh´Nubah}”(h]”Œid17”ah ]”h"]”h$]”h&]”Œrefid”Œ*accessing-the-data-attached-to-the-context”uh1hÿhjOubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjLubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjIubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒEffect of a HID-BPF program”…”�”}”(hjth²hh³Nh´Nubah}”(h]”Œid18”ah ]”h"]”h$]”h&]”Œrefid”Œeffect-of-a-hid-bpf-program”uh1hÿhjqubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjnubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjIubeh}”(h]”h ]”h"]”h$]”h&]”uh1hòhj-ubeh}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhôubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒ#Attaching a bpf program to a device”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”Œid19”ah ]”h"]”h$]”h&]”Œrefid”Œ#attaching-a-bpf-program-to-a-device”uh1hÿhjŸubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjœubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhôubhø)�”}”(hhh]”(hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒ9An (almost) complete example of a BPF enhanced HID device”…”�”}”(hjÄh²hh³Nh´Nubah}”(h]”Œid20”ah ]”h"]”h$]”h&]”Œrefid”Œ7an-almost-complete-example-of-a-bpf-enhanced-hid-device”uh1hÿhjÁubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhj¾ubhó)�”}”(hhh]”(hø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒFiltering events”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”Œid21”ah ]”h"]”h$]”h&]”Œrefid”Œfiltering-events”uh1hÿhjàubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjÚubhø)�”}”(hhh]”hÞ)�”}”(hhh]”j)�”}”(hhh]”hŒControlling the device”…”�”}”(hjh²hh³Nh´Nubah}”(h]”Œid22”ah ]”h"]”h$]”h&]”Œrefid”Œcontrolling-the-device”uh1hÿhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝhjÿubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjÚubeh}”(h]”h ]”h"]”h$]”h&]”uh1hòhj¾ubeh}”(h]”h ]”h"]”h$]”h&]”uh1h÷hhôubeh}”(h]”h ]”h"]”h$]”h&]”uh1hòhhïh²hh³Nh´Nubah}”(h]”Œcontents”ah ]”(Œcontents”Œlocal”eh"]”Œcontents”ah$]”h&]”uh1híh³hÇh´KhhÊh²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒWhen (and why) to use HID-BPF”h]”hŒWhen (and why) to use HID-BPF”…”�”}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefid”j uh1hÍhj=h²hh³hÇh´KubhÞ)�”}”(hŒYThere are several use cases when using HID-BPF is better than standard kernel driver fix:”h]”hŒYThere are several use cases when using HID-BPF is better than standard kernel driver fix:”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj=h²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒDead zone of a joystick”h]”hŒDead zone of a joystick”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNj)uh1hÍhj]h²hh³hÇh´KubhÞ)�”}”(hŒÏAssuming you have a joystick that is getting older, it is common to see it wobbling around its neutral point. This is usually filtered at the application level by adding a *dead zone* for this specific axis.”h]”(hŒ¬Assuming you have a joystick that is getting older, it is common to see it wobbling around its neutral point. This is usually filtered at the application level by adding a ”…”�”}”(hjnh²hh³Nh´NubhŒemphasis”“”)�”}”(hŒ *dead zone*”h]”hŒ dead zone”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jvhjnubhŒ for this specific axis.”…”�”}”(hjnh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj]h²hubhÞ)�”}”(hŒ›With HID-BPF, we can apply this filtering in the kernel directly so userspace does not get woken up when nothing else is happening on the input controller.”h]”hŒ›With HID-BPF, we can apply this filtering in the kernel directly so userspace does not get woken up when nothing else is happening on the input controller.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khj]h²hubhÞ)�”}”(hXOf course, given that this dead zone is specific to an individual device, we can not create a generic fix for all of the same joysticks. Adding a custom kernel API for this (e.g. by adding a sysfs entry) does not guarantee this new kernel API will be broadly adopted and maintained.”h]”hXOf course, given that this dead zone is specific to an individual device, we can not create a generic fix for all of the same joysticks. Adding a custom kernel API for this (e.g. by adding a sysfs entry) does not guarantee this new kernel API will be broadly adopted and maintained.”…”�”}”(hjžh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K!hj]h²hubhÞ)�”}”(hŒzHID-BPF allows the userspace program to load the program itself, ensuring we only load the custom API when we have a user.”h]”hŒzHID-BPF allows the userspace program to load the program itself, ensuring we only load the custom API when we have a user.”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K&hj]h²hubeh}”(h]”j/ah ]”h"]”Œdead zone of a joystick”ah$]”h&]”uh1hÈhj=h²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ!Simple fixup of report descriptor”h]”hŒ!Simple fixup of report descriptor”…”�”}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjKuh1hÍhjÁh²hh³hÇh´K*ubhÞ)�”}”(hŒ×In the HID tree, half of the drivers only fix one key or one byte in the report descriptor. These fixes all require a kernel patch and the subsequent shepherding into a release, a long and painful process for users.”h]”hŒ×In the HID tree, half of the drivers only fix one key or one byte in the report descriptor. These fixes all require a kernel patch and the subsequent shepherding into a release, a long and painful process for users.”…”�”}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K,hjÁh²hubhÞ)�”}”(hXWe can reduce this burden by providing an eBPF program instead. Once such a program has been verified by the user, we can embed the source code into the kernel tree and ship the eBPF program and load it directly instead of loading a specific kernel module for it.”h]”hXWe can reduce this burden by providing an eBPF program instead. Once such a program has been verified by the user, we can embed the source code into the kernel tree and ship the eBPF program and load it directly instead of loading a specific kernel module for it.”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K0hjÁh²hubhÞ)�”}”(hŒbNote: distribution of eBPF programs and their inclusion in the kernel is not yet fully implemented”h]”hŒbNote: distribution of eBPF programs and their inclusion in the kernel is not yet fully implemented”…”�”}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K5hjÁh²hubeh}”(h]”jQah ]”h"]”Œ!simple fixup of report descriptor”ah$]”h&]”uh1hÈhj=h²hh³hÇh´K*ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ0Add a new feature that requires a new kernel API”h]”hŒ0Add a new feature that requires a new kernel API”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjmuh1hÍhjh²hh³hÇh´K9ubhÞ)�”}”(hXµAn example for such a feature are the Universal Stylus Interface (USI) pens. Basically, USI pens require a new kernel API because there are new channels of communication that our HID and input stack do not support. Instead of using hidraw or creating new sysfs entries or ioctls, we can rely on eBPF to have the kernel API controlled by the consumer and to not impact the performances by waking up userspace every time there is an event.”h]”hXµAn example for such a feature are the Universal Stylus Interface (USI) pens. Basically, USI pens require a new kernel API because there are new channels of communication that our HID and input stack do not support. Instead of using hidraw or creating new sysfs entries or ioctls, we can rely on eBPF to have the kernel API controlled by the consumer and to not impact the performances by waking up userspace every time there is an event.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K;hjh²hubeh}”(h]”jsah ]”h"]”Œ0add a new feature that requires a new kernel api”ah$]”h&]”uh1hÈhj=h²hh³hÇh´K9ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒBMorph a device into something else and control that from userspace”h]”hŒBMorph a device into something else and control that from userspace”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNj�uh1hÍhj)h²hh³hÇh´KDubhÞ)�”}”(hX The kernel has a relatively static mapping of HID items to evdev bits. It cannot decide to dynamically transform a given device into something else as it does not have the required context and any such transformation cannot be undone (or even discovered) by userspace.”h]”hX The kernel has a relatively static mapping of HID items to evdev bits. It cannot decide to dynamically transform a given device into something else as it does not have the required context and any such transformation cannot be undone (or even discovered) by userspace.”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KFhj)h²hubhÞ)�”}”(hŒ»However, some devices are useless with that static way of defining devices. For example, the Microsoft Surface Dial is a pushbutton with haptic feedback that is barely usable as of today.”h]”hŒ»However, some devices are useless with that static way of defining devices. For example, the Microsoft Surface Dial is a pushbutton with haptic feedback that is barely usable as of today.”…”�”}”(hjHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KKhj)h²hubhÞ)�”}”(hXžWith eBPF, userspace can morph that device into a mouse, and convert the dial events into wheel events. Also, the userspace program can set/unset the haptic feedback depending on the context. For example, if a menu is visible on the screen we likely need to have a haptic click every 15 degrees. But when scrolling in a web page the user experience is better when the device emits events at the highest resolution.”h]”hXžWith eBPF, userspace can morph that device into a mouse, and convert the dial events into wheel events. Also, the userspace program can set/unset the haptic feedback depending on the context. For example, if a menu is visible on the screen we likely need to have a haptic click every 15 degrees. But when scrolling in a web page the user experience is better when the device emits events at the highest resolution.”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KOhj)h²hubeh}”(h]”j•ah ]”h"]”ŒBmorph a device into something else and control that from userspace”ah$]”h&]”uh1hÈhj=h²hh³hÇh´KDubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒFirewall”h]”hŒFirewall”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNj±uh1hÍhjkh²hh³hÇh´KWubhÞ)�”}”(hŒ†What if we want to prevent other users to access a specific feature of a device? (think a possibly broken firmware update entry point)”h]”hŒ†What if we want to prevent other users to access a specific feature of a device? (think a possibly broken firmware update entry point)”…”�”}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KYhjkh²hubhÞ)�”}”(hŒYWith eBPF, we can intercept any HID command emitted to the device and validate it or not.”h]”hŒYWith eBPF, we can intercept any HID command emitted to the device and validate it or not.”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K\hjkh²hubhÞ)�”}”(hŒ‚This also allows to sync the state between the userspace and the kernel/bpf program because we can intercept any incoming command.”h]”hŒ‚This also allows to sync the state between the userspace and the kernel/bpf program because we can intercept any incoming command.”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K_hjkh²hubeh}”(h]”j·ah ]”h"]”Œfirewall”ah$]”h&]”uh1hÈhj=h²hh³hÇh´KWubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒTracing”h]”hŒTracing”…”�”}”(hj°h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjÓuh1hÍhj­h²hh³hÇh´KcubhÞ)�”}”(hŒbThe last usage is tracing events and all the fun we can do we BPF to summarize and analyze events.”h]”hŒbThe last usage is tracing events and all the fun we can do we BPF to summarize and analyze events.”…”�”}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kehj­h²hubhÞ)�”}”(hŒQRight now, tracing relies on hidraw. It works well except for a couple of issues:”h]”hŒQRight now, tracing relies on hidraw. It works well except for a couple of issues:”…”�”}”(hjÌh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Khhj­h²hubhŒenumerated_list”“”)�”}”(hhh]”(hø)�”}”(hŒ†if the driver doesn't export a hidraw node, we can't trace anything (eBPF will be a "god-mode" there, so this may raise some eyebrows)”h]”hÞ)�”}”(hŒ†if the driver doesn't export a hidraw node, we can't trace anything (eBPF will be a "god-mode" there, so this may raise some eyebrows)”h]”hŒŽif the driver doesn’t export a hidraw node, we can’t trace anything (eBPF will be a “god-modeâ€� there, so this may raise some eyebrows)”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kkhjßubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjÜh²hh³hÇh´Nubhø)�”}”(hŒ©hidraw doesn't catch other processes' requests to the device, which means that we have cases where we need to add printks to the kernel to understand what is happening. ”h]”hÞ)�”}”(hŒ¨hidraw doesn't catch other processes' requests to the device, which means that we have cases where we need to add printks to the kernel to understand what is happening.”h]”hŒ¬hidraw doesn’t catch other processes’ requests to the device, which means that we have cases where we need to add printks to the kernel to understand what is happening.”…”�”}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kmhj÷ubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hjÜh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1jÚhj­h²hh³hÇh´Kkubeh}”(h]”jÙah ]”h"]”Œtracing”ah$]”h&]”uh1hÈhj=h²hh³hÇh´Kcubeh}”(h]”jah ]”h"]”Œwhen (and why) to use hid-bpf”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒHigh-level view of HID-BPF”h]”hŒHigh-level view of HID-BPF”…”�”}”(hj+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjuh1hÍhj(h²hh³hÇh´KrubhÞ)�”}”(hŒÞThe main idea behind HID-BPF is that it works at an array of bytes level. Thus, all of the parsing of the HID report and the HID report descriptor must be implemented in the userspace component that loads the eBPF program.”h]”hŒÞThe main idea behind HID-BPF is that it works at an array of bytes level. Thus, all of the parsing of the HID report and the HID report descriptor must be implemented in the userspace component that loads the eBPF program.”…”�”}”(hj9h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kthj(h²hubhÞ)�”}”(hŒ–For example, in the dead zone joystick from above, knowing which fields in the data stream needs to be set to ``0`` needs to be computed by userspace.”h]”(hŒnFor example, in the dead zone joystick from above, knowing which fields in the data stream needs to be set to ”…”�”}”(hjGh²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjGubhŒ# needs to be computed by userspace.”…”�”}”(hjGh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kyhj(h²hubhÞ)�”}”(hŒ­A corollary of this is that HID-BPF doesn't know about the other subsystems available in the kernel. *You can not directly emit input event through the input API from eBPF*.”h]”(hŒgA corollary of this is that HID-BPF doesn’t know about the other subsystems available in the kernel. ”…”�”}”(hjgh²hh³Nh´Nubjw)�”}”(hŒG*You can not directly emit input event through the input API from eBPF*”h]”hŒEYou can not directly emit input event through the input API from eBPF”…”�”}”(hjoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jvhjgubhŒ.”…”�”}”(hjgh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K|hj(h²hubhÞ)�”}”(hŒ©When a BPF program needs to emit input events, it needs to talk with the HID protocol, and rely on the HID kernel processing to translate the HID data into input events.”h]”hŒ©When a BPF program needs to emit input events, it needs to talk with the HID protocol, and rely on the HID kernel processing to translate the HID data into input events.”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K€hj(h²hubeh}”(h]”jah ]”h"]”Œhigh-level view of hid-bpf”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KrubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ-In-tree HID-BPF programs and ``udev-hid-bpf``”h]”(hŒIn-tree HID-BPF programs and ”…”�”}”(hjŸh²hh³Nh´Nubj")�”}”(hj%h]”hŒ udev-hid-bpf”…”�”}”(hj§h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjŸubeh}”(h]”h ]”h"]”h$]”h&]”jNj3uh1hÍhjœh²hh³hÇh´K…ubhÞ)�”}”(hŒ³Official device fixes are shipped in the kernel tree as source in the ``drivers/hid/bpf/progs`` directory. This allows to add selftests to them in ``tools/testing/selftests/hid``.”h]”(hŒFOfficial device fixes are shipped in the kernel tree as source in the ”…”�”}”(hjºh²hh³Nh´Nubj")�”}”(hŒ``drivers/hid/bpf/progs``”h]”hŒdrivers/hid/bpf/progs”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjºubhŒ4 directory. This allows to add selftests to them in ”…”�”}”(hjºh²hh³Nh´Nubj")�”}”(hŒ``tools/testing/selftests/hid``”h]”hŒtools/testing/selftests/hid”…”�”}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjºubhŒ.”…”�”}”(hjºh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K‡hjœh²hubhÞ)�”}”(hŒòHowever, the compilation of these objects is not part of a regular kernel compilation given that they need an external tool to be loaded. This tool is currently `udev-hid-bpf `_.”h]”(hŒ¡However, the compilation of these objects is not part of a regular kernel compilation given that they need an external tool to be loaded. This tool is currently ”…”�”}”(hjìh²hh³Nh´Nubj)�”}”(hŒP`udev-hid-bpf `_”h]”hŒ udev-hid-bpf”…”�”}”(hjôh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œ udev-hid-bpf”Œrefuri”Œ>https://libevdev.pages.freedesktop.org/udev-hid-bpf/index.html”uh1hÿhjìubhŒtarget”“”)�”}”(hŒA ”h]”h}”(h]”Œ udev-hid-bpf”ah ]”h"]”Œ udev-hid-bpf”ah$]”h&]”Œrefuri”juh1jŒ referenced”KhjìubhŒ.”…”�”}”(hjìh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K‹hjœh²hubhÞ)�”}”(hX|For convenience, that external repository duplicates the files from here in ``drivers/hid/bpf/progs`` into its own ``src/bpf/stable`` directory. This allows distributions to not have to pull the entire kernel source tree to ship and package those HID-BPF fixes. ``udev-hid-bpf`` also has capabilities of handling multiple objects files depending on the kernel the user is running.”h]”(hŒLFor convenience, that external repository duplicates the files from here in ”…”�”}”(hj h²hh³Nh´Nubj")�”}”(hŒ``drivers/hid/bpf/progs``”h]”hŒdrivers/hid/bpf/progs”…”�”}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ubhŒ into its own ”…”�”}”(hj h²hh³Nh´Nubj")�”}”(hŒ``src/bpf/stable``”h]”hŒsrc/bpf/stable”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ubhŒ� directory. This allows distributions to not have to pull the entire kernel source tree to ship and package those HID-BPF fixes. ”…”�”}”(hj h²hh³Nh´Nubj")�”}”(hŒ``udev-hid-bpf``”h]”hŒ udev-hid-bpf”…”�”}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ubhŒf also has capabilities of handling multiple objects files depending on the kernel the user is running.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K�hjœh²hubeh}”(h]”j9ah ]”h"]”Œ)in-tree hid-bpf programs and udev-hid-bpf”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K…ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒAvailable types of programs”h]”hŒAvailable types of programs”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjUuh1hÍhjkh²hh³hÇh´K–ubhÞ)�”}”(hŒdHID-BPF is built "on top" of BPF, meaning that we use bpf struct_ops method to declare our programs.”h]”hŒhHID-BPF is built “on topâ€� of BPF, meaning that we use bpf struct_ops method to declare our programs.”…”�”}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K˜hjkh²hubhÞ)�”}”(hŒ5HID-BPF has the following attachment types available:”h]”hŒ5HID-BPF has the following attachment types available:”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K›hjkh²hubjÛ)�”}”(hhh]”(hø)�”}”(hŒPevent processing/filtering with ``SEC("struct_ops/hid_device_event")`` in libbpf”h]”hÞ)�”}”(hj�h]”(hŒ event processing/filtering with ”…”�”}”(hjŸh²hh³Nh´Nubj")�”}”(hŒ&``SEC("struct_ops/hid_device_event")``”h]”hŒ"SEC("struct_ops/hid_device_event")”…”�”}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjŸubhŒ in libbpf”…”�”}”(hjŸh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K�hj›ubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj˜h²hh³hÇh´Nubhø)�”}”(hŒ?actions coming from userspace with ``SEC("syscall")`` in libbpf”h]”hÞ)�”}”(hjÆh]”(hŒ#actions coming from userspace with ”…”�”}”(hjÈh²hh³Nh´Nubj")�”}”(hŒ``SEC("syscall")``”h]”hŒSEC("syscall")”…”�”}”(hjÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÈubhŒ in libbpf”…”�”}”(hjÈh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KžhjÄubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj˜h²hh³hÇh´Nubhø)�”}”(hŒ€change of the report descriptor with ``SEC("struct_ops/hid_rdesc_fixup")`` or ``SEC("struct_ops.s/hid_rdesc_fixup")`` in libbpf ”h]”hÞ)�”}”(hŒchange of the report descriptor with ``SEC("struct_ops/hid_rdesc_fixup")`` or ``SEC("struct_ops.s/hid_rdesc_fixup")`` in libbpf”h]”(hŒ%change of the report descriptor with ”…”�”}”(hjñh²hh³Nh´Nubj")�”}”(hŒ%``SEC("struct_ops/hid_rdesc_fixup")``”h]”hŒ!SEC("struct_ops/hid_rdesc_fixup")”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjñubhŒ or ”…”�”}”(hjñh²hh³Nh´Nubj")�”}”(hŒ'``SEC("struct_ops.s/hid_rdesc_fixup")``”h]”hŒ#SEC("struct_ops.s/hid_rdesc_fixup")”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjñubhŒ in libbpf”…”�”}”(hjñh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KŸhjíubah}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj˜h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jjjhjjuh1jÚhjkh²hh³hÇh´K�ubhÞ)�”}”(hŒìA ``hid_device_event`` is calling a BPF program when an event is received from the device. Thus we are in IRQ context and can act on the data or notify userspace. And given that we are in IRQ context, we can not talk back to the device.”h]”(hŒA ”…”�”}”(hj/h²hh³Nh´Nubj")�”}”(hŒ``hid_device_event``”h]”hŒhid_device_event”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj/ubhŒÖ is calling a BPF program when an event is received from the device. Thus we are in IRQ context and can act on the data or notify userspace. And given that we are in IRQ context, we can not talk back to the device.”…”�”}”(hj/h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K¢hjkh²hubhÞ)�”}”(hŒ®A ``syscall`` means that userspace called the syscall ``BPF_PROG_RUN`` facility. This time, we can do any operations allowed by HID-BPF, and talking to the device is allowed.”h]”(hŒA ”…”�”}”(hjOh²hh³Nh´Nubj")�”}”(hŒ ``syscall``”h]”hŒsyscall”…”�”}”(hjWh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjOubhŒ) means that userspace called the syscall ”…”�”}”(hjOh²hh³Nh´Nubj")�”}”(hŒ``BPF_PROG_RUN``”h]”hŒ BPF_PROG_RUN”…”�”}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjOubhŒh facility. This time, we can do any operations allowed by HID-BPF, and talking to the device is allowed.”…”�”}”(hjOh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K¦hjkh²hubhÞ)�”}”(hXžLast, ``hid_rdesc_fixup`` is different from the others as there can be only one BPF program of this type. This is called on ``probe`` from the driver and allows to change the report descriptor from the BPF program. Once a ``hid_rdesc_fixup`` program has been loaded, it is not possible to overwrite it unless the program which inserted it allows us by pinning the program and closing all of its fds pointing to it.”h]”(hŒLast, ”…”�”}”(hj�h²hh³Nh´Nubj")�”}”(hŒ``hid_rdesc_fixup``”h]”hŒhid_rdesc_fixup”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj�ubhŒc is different from the others as there can be only one BPF program of this type. This is called on ”…”�”}”(hj�h²hh³Nh´Nubj")�”}”(hŒ ``probe``”h]”hŒprobe”…”�”}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj�ubhŒY from the driver and allows to change the report descriptor from the BPF program. Once a ”…”�”}”(hj�h²hh³Nh´Nubj")�”}”(hŒ``hid_rdesc_fixup``”h]”hŒhid_rdesc_fixup”…”�”}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj�ubhŒ­ program has been loaded, it is not possible to overwrite it unless the program which inserted it allows us by pinning the program and closing all of its fds pointing to it.”…”�”}”(hj�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kªhjkh²hubhÞ)�”}”(hŒeNote that ``hid_rdesc_fixup`` can be declared as sleepable (``SEC("struct_ops.s/hid_rdesc_fixup")``).”h]”(hŒ Note that ”…”�”}”(hjÅh²hh³Nh´Nubj")�”}”(hŒ``hid_rdesc_fixup``”h]”hŒhid_rdesc_fixup”…”�”}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÅubhŒ can be declared as sleepable (”…”�”}”(hjÅh²hh³Nh´Nubj")�”}”(hŒ'``SEC("struct_ops.s/hid_rdesc_fixup")``”h]”hŒ#SEC("struct_ops.s/hid_rdesc_fixup")”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÅubhŒ).”…”�”}”(hjÅh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´K°hjkh²hubeh}”(h]”j[ah ]”h"]”Œavailable types of programs”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K–ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒDeveloper API:”h]”hŒDeveloper API:”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjwuh1hÍhjþh²hh³hÇh´K´ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ%Available ``struct_ops`` for HID-BPF:”h]”(hŒ Available ”…”�”}”(hj h²hh³Nh´Nubj")�”}”(hj–h]”hŒ struct_ops”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ubhŒ for HID-BPF:”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jNj¨uh1hÍhj h²hh³hÇh´K·ubhŒindex”“”)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(Œsingle”Œhid_bpf_ops (C struct)”Œ c.hid_bpf_ops”hNt”auh1j1 hj h²hh³Nh´NubhŒdesc”“”)�”}”(hhh]”(hŒdesc_signature”“”)�”}”(hŒ hid_bpf_ops”h]”hŒdesc_signature_line”“”)�”}”(hŒstruct hid_bpf_ops”h]”(hŒdesc_sig_keyword”“”)�”}”(hŒstruct”h]”hŒstruct”…”�”}”(hjU h²hh³Nh´Nubah}”(h]”h ]”Œk”ah"]”h$]”h&]”uh1jS hjO h²hh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KubhŒdesc_sig_space”“”)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjg h²hh³Nh´Nubah}”(h]”h ]”Œw”ah"]”h$]”h&]”uh1je hjO h²hh³jd h´KubhŒ desc_name”“”)�”}”(hŒ hid_bpf_ops”h]”hŒ desc_sig_name”“”)�”}”(hjK h]”hŒ hid_bpf_ops”…”�”}”(hj~ h²hh³Nh´Nubah}”(h]”h ]”Œn”ah"]”h$]”h&]”uh1j| hjx ubah}”(h]”h ]”(Œsig-name”Œdescname”eh"]”h$]”h&]”hÅhÆuh1jv hjO h²hh³jd h´Kubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒ add_permalink”ˆuh1jM Œsphinx_line_type”Œ declarator”hjI h²hh³jd h´Kubah}”(h]”j@ ah ]”(Œsig”Œ sig-object”eh"]”h$]”h&]”Œ is_multiline”ˆŒ _toc_parts”)Œ _toc_name”huh1jG h³jd h´KhjD h²hubhŒ desc_content”“”)�”}”(hhh]”hÞ)�”}”(hŒQA BPF struct_ops of callbacks allowing to attach HID-BPF programs to a HID device”h]”hŒQA BPF struct_ops of callbacks allowing to attach HID-BPF programs to a HID device”…”�”}”(hj­ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KThjª h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hjD h²hh³jd h´Kubeh}”(h]”h ]”(Œc”Œstruct”eh"]”h$]”h&]”Œdomain”jÅ Œobjtype”jÆ Œdesctype”jÆ Œnoindex”‰Œ noindexentry”‰Œnocontentsentry”‰uh1jB h²hhj h³Nh´NubhŒ container”“”)�”}”(hX **Definition**:: struct hid_bpf_ops { int hid_id; u32 flags; int (*hid_device_event)(struct hid_bpf_ctx *ctx, enum hid_report_type report_type, u64 source); int (*hid_rdesc_fixup)(struct hid_bpf_ctx *ctx); int (*hid_hw_request)(struct hid_bpf_ctx *ctx, unsigned char reportnum, enum hid_report_type rtype, enum hid_class_request reqtype, u64 source); int (*hid_hw_output_report)(struct hid_bpf_ctx *ctx, u64 source); }; **Members** ``hid_id`` the HID uniq ID to attach to. This is writeable before ``load()``, and cannot be changed after ``flags`` flags used while attaching the struct_ops to the device. Currently only available value is ``0`` or ``BPF_F_BEFORE``. Writeable only before ``load()`` ``hid_device_event`` called whenever an event is coming in from the device It has the following arguments: ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx ` Return: ``0`` on success and keep processing; a positive value to change the incoming size buffer; a negative error code to interrupt the processing of this event Context: Interrupt context. ``hid_rdesc_fixup`` called when the probe function parses the report descriptor of the HID device It has the following arguments: ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx ` Return: ``0`` on success and keep processing; a positive value to change the incoming size buffer; a negative error code to interrupt the processing of this device ``hid_hw_request`` called whenever a hid_hw_raw_request() call is emitted on the HID device It has the following arguments: ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx ` ``reportnum``: the report number, as in hid_hw_raw_request() ``rtype``: the report type (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``) ``reqtype``: the request ``source``: a u64 referring to a uniq but identifiable source. If ``0``, the kernel itself emitted that call. For hidraw, ``source`` is set to the associated ``struct file *``. Return: ``0`` to keep processing the request by hid-core; any other value stops hid-core from processing that event. A positive value should be returned with the number of bytes returned in the incoming buffer; a negative error code interrupts the processing of this call. ``hid_hw_output_report`` called whenever a hid_hw_output_report() call is emitted on the HID device It has the following arguments: ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx ` ``source``: a u64 referring to a uniq but identifiable source. If ``0``, the kernel itself emitted that call. For hidraw, ``source`` is set to the associated ``struct file *``. Return: ``0`` to keep processing the request by hid-core; any other value stops hid-core from processing that event. A positive value should be returned with the number of bytes written to the device; a negative error code interrupts the processing of this call.”h]”(hÞ)�”}”(hŒ**Definition**::”h]”(hŒstrong”“”)�”}”(hŒ**Definition**”h]”hŒ Definition”…”�”}”(hjÜ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjÖ ubhŒ:”…”�”}”(hjÖ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KXhjÒ ubhŒ literal_block”“”)�”}”(hXªstruct hid_bpf_ops { int hid_id; u32 flags; int (*hid_device_event)(struct hid_bpf_ctx *ctx, enum hid_report_type report_type, u64 source); int (*hid_rdesc_fixup)(struct hid_bpf_ctx *ctx); int (*hid_hw_request)(struct hid_bpf_ctx *ctx, unsigned char reportnum, enum hid_report_type rtype, enum hid_class_request reqtype, u64 source); int (*hid_hw_output_report)(struct hid_bpf_ctx *ctx, u64 source); };”h]”hXªstruct hid_bpf_ops { int hid_id; u32 flags; int (*hid_device_event)(struct hid_bpf_ctx *ctx, enum hid_report_type report_type, u64 source); int (*hid_rdesc_fixup)(struct hid_bpf_ctx *ctx); int (*hid_hw_request)(struct hid_bpf_ctx *ctx, unsigned char reportnum, enum hid_report_type rtype, enum hid_class_request reqtype, u64 source); int (*hid_hw_output_report)(struct hid_bpf_ctx *ctx, u64 source); };”…”�”}”hj÷ sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jõ h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KZhjÒ ubhÞ)�”}”(hŒ **Members**”h]”jÛ )�”}”(hj h]”hŒMembers”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KchjÒ ubhŒdefinition_list”“”)�”}”(hhh]”(hŒdefinition_list_item”“”)�”}”(hŒj``hid_id`` the HID uniq ID to attach to. This is writeable before ``load()``, and cannot be changed after ”h]”(hŒterm”“”)�”}”(hŒ ``hid_id``”h]”j")�”}”(hj- h]”hŒhid_id”…”�”}”(hj/ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj+ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KXhj% ubhŒ definition”“”)�”}”(hhh]”hÞ)�”}”(hŒ^the HID uniq ID to attach to. This is writeable before ``load()``, and cannot be changed after”h]”(hŒ7the HID uniq ID to attach to. This is writeable before ”…”�”}”(hjH h²hh³Nh´Nubj")�”}”(hŒ ``load()``”h]”hŒload()”…”�”}”(hjP h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjH ubhŒ, and cannot be changed after”…”�”}”(hjH h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KWhjE ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj% ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jB h´KXhj ubj$ )�”}”(hŒ¡``flags`` flags used while attaching the struct_ops to the device. Currently only available value is ``0`` or ``BPF_F_BEFORE``. Writeable only before ``load()`` ”h]”(j* )�”}”(hŒ ``flags``”h]”j")�”}”(hj{ h]”hŒflags”…”�”}”(hj} h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjy ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K[hju ubjD )�”}”(hhh]”hÞ)�”}”(hŒ–flags used while attaching the struct_ops to the device. Currently only available value is ``0`` or ``BPF_F_BEFORE``. Writeable only before ``load()``”h]”(hŒ[flags used while attaching the struct_ops to the device. Currently only available value is ”…”�”}”(hj” h²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hjœ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj” ubhŒ or ”…”�”}”(hj” h²hh³Nh´Nubj")�”}”(hŒ``BPF_F_BEFORE``”h]”hŒ BPF_F_BEFORE”…”�”}”(hj® h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj” ubhŒ. Writeable only before ”…”�”}”(hj” h²hh³Nh´Nubj")�”}”(hŒ ``load()``”h]”hŒload()”…”�”}”(hjÀ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj” ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KYhj‘ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hju ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j� h´K[hj ubj$ )�”}”(hXy``hid_device_event`` called whenever an event is coming in from the device It has the following arguments: ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx ` Return: ``0`` on success and keep processing; a positive value to change the incoming size buffer; a negative error code to interrupt the processing of this event Context: Interrupt context. ”h]”(j* )�”}”(hŒ``hid_device_event``”h]”j")�”}”(hjç h]”hŒhid_device_event”…”�”}”(hjé h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjå ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Kthjá ubjD )�”}”(hhh]”(hÞ)�”}”(hŒ5called whenever an event is coming in from the device”h]”hŒ5called whenever an event is coming in from the device”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Kjhjý ubhÞ)�”}”(hŒIt has the following arguments:”h]”hŒIt has the following arguments:”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Klhjý ubhÞ)�”}”(hŒJ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx `”h]”(j")�”}”(hŒ``ctx``”h]”hŒctx”…”�”}”(hj" h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ubhŒ: The HID-BPF context as ”…”�”}”(hj h²hh³Nh´Nubh)�”}”(hŒ*:c:type:`struct hid_bpf_ctx `”h]”j")�”}”(hj6 h]”hŒstruct hid_bpf_ctx”…”�”}”(hj8 h²hh³Nh´Nubah}”(h]”h ]”(Œxref”jÅ Œc-type”eh"]”h$]”h&]”uh1j!hj4 ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œ hid/hid-bpf”Œ refdomain”jÅ Œreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰Œ c:parent_key”Œsphinx.domains.c”Œ LookupKey”“”)�”}”Œdata”]”sbŒ reftarget”Œ hid_bpf_ctx”uh1hh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Knhj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j^ h´Knhjý ubhÞ)�”}”(hŒ¢Return: ``0`` on success and keep processing; a positive value to change the incoming size buffer; a negative error code to interrupt the processing of this event”h]”(hŒReturn: ”…”�”}”(hje h²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hjm h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hje ubhŒ• on success and keep processing; a positive value to change the incoming size buffer; a negative error code to interrupt the processing of this event”…”�”}”(hje h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Kphjý ubhÞ)�”}”(hŒContext: Interrupt context.”h]”hŒContext: Interrupt context.”…”�”}”(hj† h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jü h´Kthjý ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jC hjá ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jü h´Kthj ubj$ )�”}”(hXt``hid_rdesc_fixup`` called when the probe function parses the report descriptor of the HID device It has the following arguments: ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx ` Return: ``0`` on success and keep processing; a positive value to change the incoming size buffer; a negative error code to interrupt the processing of this device ”h]”(j* )�”}”(hŒ``hid_rdesc_fixup``”h]”j")�”}”(hj¦ h]”hŒhid_rdesc_fixup”…”�”}”(hj¨ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¤ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Kƒhj  ubjD )�”}”(hhh]”(hÞ)�”}”(hŒMcalled when the probe function parses the report descriptor of the HID device”h]”hŒMcalled when the probe function parses the report descriptor of the HID device”…”�”}”(hj¿ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Kzhj¼ ubhÞ)�”}”(hŒIt has the following arguments:”h]”hŒIt has the following arguments:”…”�”}”(hjÎ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K}hj¼ ubhÞ)�”}”(hŒJ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx `”h]”(j")�”}”(hŒ``ctx``”h]”hŒctx”…”�”}”(hjá h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÝ ubhŒ: The HID-BPF context as ”…”�”}”(hjÝ h²hh³Nh´Nubh)�”}”(hŒ*:c:type:`struct hid_bpf_ctx `”h]”j")�”}”(hjõ h]”hŒstruct hid_bpf_ctx”…”�”}”(hj÷ h²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-type”eh"]”h$]”h&]”uh1j!hjó ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jT jX j\ Œ hid_bpf_ctx”uh1hh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´KhjÝ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j h´Khj¼ ubhÞ)�”}”(hŒ£Return: ``0`` on success and keep processing; a positive value to change the incoming size buffer; a negative error code to interrupt the processing of this device”h]”(hŒReturn: ”…”�”}”(hj h²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hj! h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ubhŒ– on success and keep processing; a positive value to change the incoming size buffer; a negative error code to interrupt the processing of this device”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K�hj¼ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jC hj  ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j» h´Kƒhj ubj$ )�”}”(hXG``hid_hw_request`` called whenever a hid_hw_raw_request() call is emitted on the HID device It has the following arguments: ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx ` ``reportnum``: the report number, as in hid_hw_raw_request() ``rtype``: the report type (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``) ``reqtype``: the request ``source``: a u64 referring to a uniq but identifiable source. If ``0``, the kernel itself emitted that call. For hidraw, ``source`` is set to the associated ``struct file *``. Return: ``0`` to keep processing the request by hid-core; any other value stops hid-core from processing that event. A positive value should be returned with the number of bytes returned in the incoming buffer; a negative error code interrupts the processing of this call. ”h]”(j* )�”}”(hŒ``hid_hw_request``”h]”j")�”}”(hjL h]”hŒhid_hw_request”…”�”}”(hjN h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjJ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K�hjF ubjD )�”}”(hhh]”(hÞ)�”}”(hŒHcalled whenever a hid_hw_raw_request() call is emitted on the HID device”h]”hŒHcalled whenever a hid_hw_raw_request() call is emitted on the HID device”…”�”}”(hje h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Kˆhjb ubhÞ)�”}”(hŒIt has the following arguments:”h]”hŒIt has the following arguments:”…”�”}”(hjt h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K‹hjb ubhÞ)�”}”(hŒJ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx `”h]”(j")�”}”(hŒ``ctx``”h]”hŒctx”…”�”}”(hj‡ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjƒ ubhŒ: The HID-BPF context as ”…”�”}”(hjƒ h²hh³Nh´Nubh)�”}”(hŒ*:c:type:`struct hid_bpf_ctx `”h]”j")�”}”(hj› h]”hŒstruct hid_bpf_ctx”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-type”eh"]”h$]”h&]”uh1j!hj™ ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jT jX j\ Œ hid_bpf_ctx”uh1hh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K�hjƒ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j¸ h´K�hjb ubhÞ)�”}”(hŒ<``reportnum``: the report number, as in hid_hw_raw_request()”h]”(j")�”}”(hŒ ``reportnum``”h]”hŒ reportnum”…”�”}”(hjà h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¿ ubhŒ/: the report number, as in hid_hw_raw_request()”…”�”}”(hj¿ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K�hjb ubhÞ)�”}”(hŒ```rtype``: the report type (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``)”h]”(j")�”}”(hŒ ``rtype``”h]”hŒrtype”…”�”}”(hjà h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÜ ubhŒ: the report type (”…”�”}”(hjÜ h²hh³Nh´Nubj")�”}”(hŒ``HID_INPUT_REPORT``”h]”hŒHID_INPUT_REPORT”…”�”}”(hjò h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÜ ubhŒ, ”…”�”}”(hjÜ h²hh³Nh´Nubj")�”}”(hŒ``HID_FEATURE_REPORT``”h]”hŒHID_FEATURE_REPORT”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÜ ubhŒ, ”…”�”}”(hjÜ h²hh³Nh´Nubj")�”}”(hŒ``HID_OUTPUT_REPORT``”h]”hŒHID_OUTPUT_REPORT”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÜ ubhŒ)”…”�”}”(hjÜ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K‘hjb ubhÞ)�”}”(hŒ``reqtype``: the request”h]”(j")�”}”(hŒ ``reqtype``”h]”hŒreqtype”…”�”}”(hj3 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj/ ubhŒ : the request”…”�”}”(hj/ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K”hjb ubhÞ)�”}”(hŒ°``source``: a u64 referring to a uniq but identifiable source. If ``0``, the kernel itself emitted that call. For hidraw, ``source`` is set to the associated ``struct file *``.”h]”(j")�”}”(hŒ ``source``”h]”hŒsource”…”�”}”(hjP h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjL ubhŒ8: a u64 referring to a uniq but identifiable source. If ”…”�”}”(hjL h²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hjb h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjL ubhŒ3, the kernel itself emitted that call. For hidraw, ”…”�”}”(hjL h²hh³Nh´Nubj")�”}”(hŒ ``source``”h]”hŒsource”…”�”}”(hjt h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjL ubhŒ is set to the associated ”…”�”}”(hjL h²hh³Nh´Nubj")�”}”(hŒ``struct file *``”h]”hŒ struct file *”…”�”}”(hj† h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjL ubhŒ.”…”�”}”(hjL h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K–hjb ubhÞ)�”}”(hXReturn: ``0`` to keep processing the request by hid-core; any other value stops hid-core from processing that event. A positive value should be returned with the number of bytes returned in the incoming buffer; a negative error code interrupts the processing of this call.”h]”(hŒReturn: ”…”�”}”(hjŸ h²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hj§ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjŸ ubhX to keep processing the request by hid-core; any other value stops hid-core from processing that event. A positive value should be returned with the number of bytes returned in the incoming buffer; a negative error code interrupts the processing of this call.”…”�”}”(hjŸ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´Kšhjb ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jC hjF ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³ja h´K�hj ubj$ )�”}”(hXŠ``hid_hw_output_report`` called whenever a hid_hw_output_report() call is emitted on the HID device It has the following arguments: ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx ` ``source``: a u64 referring to a uniq but identifiable source. If ``0``, the kernel itself emitted that call. For hidraw, ``source`` is set to the associated ``struct file *``. Return: ``0`` to keep processing the request by hid-core; any other value stops hid-core from processing that event. A positive value should be returned with the number of bytes written to the device; a negative error code interrupts the processing of this call.”h]”(j* )�”}”(hŒ``hid_hw_output_report``”h]”j")�”}”(hjÒ h]”hŒhid_hw_output_report”…”�”}”(hjÔ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÐ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K±hjÌ ubjD )�”}”(hhh]”(hÞ)�”}”(hŒJcalled whenever a hid_hw_output_report() call is emitted on the HID device”h]”hŒJcalled whenever a hid_hw_output_report() call is emitted on the HID device”…”�”}”(hjë h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K¤hjè ubhÞ)�”}”(hŒIt has the following arguments:”h]”hŒIt has the following arguments:”…”�”}”(hjú h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K§hjè ubhÞ)�”}”(hŒJ``ctx``: The HID-BPF context as :c:type:`struct hid_bpf_ctx `”h]”(j")�”}”(hŒ``ctx``”h]”hŒctx”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ubhŒ: The HID-BPF context as ”…”�”}”(hj h²hh³Nh´Nubh)�”}”(hŒ*:c:type:`struct hid_bpf_ctx `”h]”j")�”}”(hj!h]”hŒstruct hid_bpf_ctx”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-type”eh"]”h$]”h&]”uh1j!hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jT jX j\ Œ hid_bpf_ctx”uh1hh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K©hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j>h´K©hjè ubhÞ)�”}”(hŒ°``source``: a u64 referring to a uniq but identifiable source. If ``0``, the kernel itself emitted that call. For hidraw, ``source`` is set to the associated ``struct file *``.”h]”(j")�”}”(hŒ ``source``”h]”hŒsource”…”�”}”(hjIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjEubhŒ8: a u64 referring to a uniq but identifiable source. If ”…”�”}”(hjEh²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hj[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjEubhŒ3, the kernel itself emitted that call. For hidraw, ”…”�”}”(hjEh²hh³Nh´Nubj")�”}”(hŒ ``source``”h]”hŒsource”…”�”}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjEubhŒ is set to the associated ”…”�”}”(hjEh²hh³Nh´Nubj")�”}”(hŒ``struct file *``”h]”hŒ struct file *”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjEubhŒ.”…”�”}”(hjEh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K«hjè ubhÞ)�”}”(hXReturn: ``0`` to keep processing the request by hid-core; any other value stops hid-core from processing that event. A positive value should be returned with the number of bytes written to the device; a negative error code interrupts the processing of this call.”h]”(hŒReturn: ”…”�”}”(hj˜h²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj˜ubhŒù to keep processing the request by hid-core; any other value stops hid-core from processing that event. A positive value should be returned with the number of bytes written to the device; a negative error code interrupts the processing of this call.”…”�”}”(hj˜h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:185: ./include/linux/hid_bpf.h”h´K¯hjè ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jC hjÌ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jç h´K±hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hjÒ ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hj h²hh³Nh´Nubeh}”(h]”j®ah ]”h"]”Œ!available struct_ops for hid-bpf:”ah$]”h&]”uh1hÈhjþh²hh³hÇh´K·ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ/User API data structures available in programs:”h]”hŒ/User API data structures available in programs:”…”�”}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjÊuh1hÍhjÙh²hh³hÇh´K¾ubj2 )�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j> Œhid_bpf_ctx (C struct)”Œ c.hid_bpf_ctx”hNt”auh1j1 hjÙh²hh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´NubjC )�”}”(hhh]”(jH )�”}”(hŒ hid_bpf_ctx”h]”jN )�”}”(hŒstruct hid_bpf_ctx”h]”(jT )�”}”(hjW h]”hŒstruct”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjh²hh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´Kubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjh²hh³jh´Kubjw )�”}”(hŒ hid_bpf_ctx”h]”j} )�”}”(hjþh]”hŒ hid_bpf_ctx”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj ubah}”(h]”h ]”(j� j� eh"]”h$]”h&]”hÅhÆuh1jv hjh²hh³jh´Kubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjš ˆuh1jM j› jœ hjüh²hh³jh´Kubah}”(h]”jöah ]”(j  j¡ eh"]”h$]”h&]”j¥ ˆj¦ )j§ huh1jG h³jh´Khjùh²hubj© )�”}”(hhh]”hÞ)�”}”(hŒ)User accessible data for all HID programs”h]”hŒ)User accessible data for all HID programs”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´KhjCh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hjùh²hh³jh´Kubeh}”(h]”h ]”(jÅ Œstruct”eh"]”h$]”h&]”jÊ jÅ jË j^jÌ j^jÍ ‰jÎ ‰jÏ ‰uh1jB h²hhjÙh³jøh´NubjÑ )�”}”(hX½**Definition**:: struct hid_bpf_ctx { struct hid_device *hid; __u32 allocated_size; union { __s32 retval; __s32 size; }; }; **Members** ``hid`` the :c:type:`struct hid_device ` representing the device itself ``allocated_size`` Allocated size of data. ``{unnamed_union}`` anonymous ``retval`` Return value of the previous program. ``size`` Valid data in the data field.”h]”(hÞ)�”}”(hŒ**Definition**::”h]”(jÛ )�”}”(hŒ**Definition**”h]”hŒ Definition”…”�”}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjfubhŒ:”…”�”}”(hjfh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´Khjbubjö )�”}”(hŒŠstruct hid_bpf_ctx { struct hid_device *hid; __u32 allocated_size; union { __s32 retval; __s32 size; }; };”h]”hŒŠstruct hid_bpf_ctx { struct hid_device *hid; __u32 allocated_size; union { __s32 retval; __s32 size; }; };”…”�”}”hjƒsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jõ h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´KhjbubhÞ)�”}”(hŒ **Members**”h]”jÛ )�”}”(hj”h]”hŒMembers”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj’ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´K$hjbubj )�”}”(hhh]”(j$ )�”}”(hŒT``hid`` the :c:type:`struct hid_device ` representing the device itself ”h]”(j* )�”}”(hŒ``hid``”h]”j")�”}”(hj³h]”hŒhid”…”�”}”(hjµh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj±ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´Khj­ubjD )�”}”(hhh]”hÞ)�”}”(hŒKthe :c:type:`struct hid_device ` representing the device itself”h]”(hŒthe ”…”�”}”(hjÌh²hh³Nh´Nubh)�”}”(hŒ(:c:type:`struct hid_device `”h]”j")�”}”(hjÖh]”hŒstruct hid_device”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-type”eh"]”h$]”h&]”uh1j!hjÔubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jT jX j\ Œ hid_device”uh1hh³jÈh´KhjÌubhŒ representing the device itself”…”�”}”(hjÌh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jÈh´KhjÉubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj­ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jÈh´Khjªubj$ )�”}”(hŒ+``allocated_size`` Allocated size of data. ”h]”(j* )�”}”(hŒ``allocated_size``”h]”j")�”}”(hjh]”hŒallocated_size”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´Khj ubjD )�”}”(hhh]”hÞ)�”}”(hŒAllocated size of data.”h]”hŒAllocated size of data.”…”�”}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j$h´Khj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j$h´Khjªubj$ )�”}”(hŒ``{unnamed_union}`` anonymous ”h]”(j* )�”}”(hŒ``{unnamed_union}``”h]”j")�”}”(hjHh]”hŒ{unnamed_union}”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjFubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´KhjBubjD )�”}”(hhh]”hÞ)�”}”(hŒ anonymous”h]”hŒ anonymous”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j]h´Khj^ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjBubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j]h´Khjªubj$ )�”}”(hŒ1``retval`` Return value of the previous program. ”h]”(j* )�”}”(hŒ ``retval``”h]”j")�”}”(hj�h]”hŒretval”…”�”}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´K+hj{ubjD )�”}”(hhh]”hÞ)�”}”(hŒ%Return value of the previous program.”h]”hŒ%Return value of the previous program.”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j–h´K+hj—ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj{ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j–h´K+hjªubj$ )�”}”(hŒ&``size`` Valid data in the data field.”h]”(j* )�”}”(hŒ``size``”h]”j")�”}”(hjºh]”hŒsize”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¸ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”•h´K!hj´ubjD )�”}”(hhh]”hÞ)�”}”(hŒValid data in the data field.”h]”hŒValid data in the data field.”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´K"hjÐubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj´ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jÏh´K!hjªubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hjbubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hjÙh²hh³jøh´NubhÞ)�”}”(hŒ**Description**”h]”jÛ )�”}”(hjýh]”hŒ Description”…”�”}”(hjÿh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjûubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´K%hjÙh²hubhÞ)�”}”(hŒŒ``data`` is not directly accessible from the context. We need to issue a call to hid_bpf_get_data() in order to get a pointer to that field.”h]”(j")�”}”(hŒ``data``”h]”hŒdata”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubhŒ„ is not directly accessible from the context. We need to issue a call to hid_bpf_get_data() in order to get a pointer to that field.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´KhjÙh²hubhŒ block_quote”“”)�”}”(hX  This is how much memory is available and can be requested by the HID program. Note that for ``HID_BPF_RDESC_FIXUP``, that memory is set to ``4096`` (4 KB) Programs can get the available valid size in data by fetching this field. Programs can also change this value by returning a positive number in the program. To discard the event, return a negative error code. ``size`` must always be less or equal than ``allocated_size`` (it is enforced once all BPF programs have been run). ”h]”(j1)�”}”(hŒ›This is how much memory is available and can be requested by the HID program. Note that for ``HID_BPF_RDESC_FIXUP``, that memory is set to ``4096`` (4 KB) ”h]”hÞ)�”}”(hŒšThis is how much memory is available and can be requested by the HID program. Note that for ``HID_BPF_RDESC_FIXUP``, that memory is set to ``4096`` (4 KB)”h]”(hŒ\This is how much memory is available and can be requested by the HID program. Note that for ”…”�”}”(hj:h²hh³Nh´Nubj")�”}”(hŒ``HID_BPF_RDESC_FIXUP``”h]”hŒHID_BPF_RDESC_FIXUP”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj:ubhŒ, that memory is set to ”…”�”}”(hj:h²hh³Nh´Nubj")�”}”(hŒ``4096``”h]”hŒ4096”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj:ubhŒ (4 KB)”…”�”}”(hj:h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´Khj6ubah}”(h]”h ]”h"]”h$]”h&]”uh1j0h³jlh´Khj2ubhÞ)�”}”(hŒÐPrograms can get the available valid size in data by fetching this field. Programs can also change this value by returning a positive number in the program. To discard the event, return a negative error code.”h]”hŒÐPrograms can get the available valid size in data by fetching this field. Programs can also change this value by returning a positive number in the program. To discard the event, return a negative error code.”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´Khj2ubhÞ)�”}”(hŒs``size`` must always be less or equal than ``allocated_size`` (it is enforced once all BPF programs have been run).”h]”(j")�”}”(hŒ``size``”h]”hŒsize”…”�”}”(hj†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj‚ubhŒ# must always be less or equal than ”…”�”}”(hj‚h²hh³Nh´Nubj")�”}”(hŒ``allocated_size``”h]”hŒallocated_size”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj‚ubhŒ6 (it is enforced once all BPF programs have been run).”…”�”}”(hj‚h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´K$hj2ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j0h³jlh´KhjÙh²hubhÞ)�”}”(hŒU``hid`` and ``allocated_size`` are read-only, ``size`` and ``retval`` are read-write.”h]”(j")�”}”(hŒ``hid``”h]”hŒhid”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj·ubhŒ and ”…”�”}”(hj·h²hh³Nh´Nubj")�”}”(hŒ``allocated_size``”h]”hŒallocated_size”…”�”}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj·ubhŒ are read-only, ”…”�”}”(hj·h²hh³Nh´Nubj")�”}”(hŒ``size``”h]”hŒsize”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj·ubhŒ and ”…”�”}”hj·sbj")�”}”(hŒ ``retval``”h]”hŒretval”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj·ubhŒ are read-write.”…”�”}”(hj·h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³ŒT/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:192: ./include/linux/hid_bpf.h”h´K'hjÙh²hubeh}”(h]”jÐah ]”h"]”Œ/user api data structures available in programs:”ah$]”h&]”uh1hÈhjþh²hh³hÇh´K¾ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒBAvailable API that can be used in all HID-BPF struct_ops programs:”h]”hŒBAvailable API that can be used in all HID-BPF struct_ops programs:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjìuh1hÍhjh²hh³hÇh´KÄubj2 )�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j> Œhid_bpf_get_data (C function)”Œc.hid_bpf_get_data”hNt”auh1j1 hjh²hh³Nh´NubjC )�”}”(hhh]”(jH )�”}”(hŒn__bpf_kfunc __u8 * hid_bpf_get_data (struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size)”h]”jN )�”}”(hŒl__bpf_kfunc __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size)”h]”(hŒ __bpf_kfunc”…”�”}”(hj7h²hh³Nh´Nubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj7h²hh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:198: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M ubh)�”}”(hhh]”j} )�”}”(hŒ__u8”h]”hŒ__u8”…”�”}”(hjQh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjNubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”Œ identifier”Œ reftarget”jSŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jU Œ ASTIdentifier”“”)�”}”jgŒhid_bpf_get_data”sbŒc.hid_bpf_get_data”†”asbuh1hhj7h²hh³jMh´M ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjuh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj7h²hh³jMh´M ubhŒdesc_sig_punctuation”“”)�”}”(hŒ*”h]”hŒ*”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”Œp”ah"]”h$]”h&]”uh1jƒhj7h²hh³jMh´M ubjw )�”}”(hŒhid_bpf_get_data”h]”j} )�”}”(hjrh]”hŒhid_bpf_get_data”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj”ubah}”(h]”h ]”(j� j� eh"]”h$]”h&]”hÅhÆuh1jv hj7h²hh³jMh´M ubhŒdesc_parameterlist”“”)�”}”(hŒJ(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size)”h]”(hŒdesc_parameter”“”)�”}”(hŒstruct hid_bpf_ctx *ctx”h]”(jT )�”}”(hjW h]”hŒstruct”…”�”}”(hj·h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hj³ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj³ubh)�”}”(hhh]”j} )�”}”(hŒ hid_bpf_ctx”h]”hŒ hid_bpf_ctx”…”�”}”(hjÕh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjÒubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”j׌modname”NŒ classname”NjT jW )�”}”jZ ]”jpŒc.hid_bpf_get_data”†”asbuh1hhj³ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjóh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj³ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhj³ubj} )�”}”(hŒctx”h]”hŒctx”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj³ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj­ubj²)�”}”(hŒunsigned int offset”h]”(hŒdesc_sig_keyword_type”“”)�”}”(hŒunsigned”h]”hŒunsigned”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”Œkt”ah"]”h$]”h&]”uh1j'hj#ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj#ubj()�”}”(hŒint”h]”hŒint”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”j4ah"]”h$]”h&]”uh1j'hj#ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj#ubj} )�”}”(hŒoffset”h]”hŒoffset”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj#ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj­ubj²)�”}”(hŒconst size_t rdwr_buf_size”h]”(jT )�”}”(hŒconst”h]”hŒconst”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjwubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjwubh)�”}”(hhh]”j} )�”}”(hŒsize_t”h]”hŒsize_t”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj—ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jœŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jpŒc.hid_bpf_get_data”†”asbuh1hhjwubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¸h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjwubj} )�”}”(hŒ rdwr_buf_size”h]”hŒ rdwr_buf_size”…”�”}”(hjÆh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjwubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj­ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j«hj7h²hh³jMh´M ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjš ˆuh1jM j› jœ hj3h²hh³jMh´M ubah}”(h]”j.ah ]”(j  j¡ eh"]”h$]”h&]”j¥ ˆj¦ )j§ huh1jG h³jMh´M hj0h²hubj© )�”}”(hhh]”hÞ)�”}”(hŒAGet the kernel memory pointer associated with the context **ctx**”h]”(hŒ:Get the kernel memory pointer associated with the context ”…”�”}”(hjðh²hh³Nh´NubjÛ )�”}”(hŒ**ctx**”h]”hŒctx”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjðubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:198: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M hjíh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hj0h²hh³jMh´M ubeh}”(h]”h ]”(jÅ Œfunction”eh"]”h$]”h&]”jÊ jÅ jË jjÌ jjÍ ‰jÎ ‰jÏ ‰uh1jB h²hhjh³Nh´NubjÑ )�”}”(hX**Parameters** ``struct hid_bpf_ctx *ctx`` The HID-BPF context ``unsigned int offset`` The offset within the memory ``const size_t rdwr_buf_size`` the const size of the buffer **Description** **returns** ``NULL`` on error, an ``__u8`` memory pointer on success”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jÛ )�”}”(hj h]”hŒ Parameters”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:198: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M$hjubj )�”}”(hhh]”(j$ )�”}”(hŒ0``struct hid_bpf_ctx *ctx`` The HID-BPF context ”h]”(j* )�”}”(hŒ``struct hid_bpf_ctx *ctx``”h]”j")�”}”(hj?h]”hŒstruct hid_bpf_ctx *ctx”…”�”}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj=ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:198: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M"hj9ubjD )�”}”(hhh]”hÞ)�”}”(hŒThe HID-BPF context”h]”hŒThe HID-BPF context”…”�”}”(hjXh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jTh´M"hjUubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj9ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jTh´M"hj6ubj$ )�”}”(hŒ5``unsigned int offset`` The offset within the memory ”h]”(j* )�”}”(hŒ``unsigned int offset``”h]”j")�”}”(hjxh]”hŒunsigned int offset”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjvubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:198: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M#hjrubjD )�”}”(hhh]”hÞ)�”}”(hŒThe offset within the memory”h]”hŒThe offset within the memory”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j�h´M#hjŽubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjrubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j�h´M#hj6ubj$ )�”}”(hŒ<``const size_t rdwr_buf_size`` the const size of the buffer ”h]”(j* )�”}”(hŒ``const size_t rdwr_buf_size``”h]”j")�”}”(hj±h]”hŒconst size_t rdwr_buf_size”…”�”}”(hj³h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¯ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:198: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M$hj«ubjD )�”}”(hhh]”hÞ)�”}”(hŒthe const size of the buffer”h]”hŒthe const size of the buffer”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jÆh´M$hjÇubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj«ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jÆh´M$hj6ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hjubhÞ)�”}”(hŒ**Description**”h]”jÛ )�”}”(hjìh]”hŒ Description”…”�”}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjêubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:198: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M&hjubhÞ)�”}”(hŒD**returns** ``NULL`` on error, an ``__u8`` memory pointer on success”h]”(jÛ )�”}”(hŒ **returns**”h]”hŒreturns”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjubhŒ ”…”�”}”(hjh²hh³Nh´Nubj")�”}”(hŒ``NULL``”h]”hŒNULL”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubhŒ on error, an ”…”�”}”(hjh²hh³Nh´Nubj")�”}”(hŒ``__u8``”h]”hŒ__u8”…”�”}”(hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubhŒ memory pointer on success”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:198: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M%hjubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hjh²hh³Nh´Nubeh}”(h]”jòah ]”h"]”ŒBavailable api that can be used in all hid-bpf struct_ops programs:”ah$]”h&]”uh1hÈhjþh²hh³hÇh´KÄubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒgAvailable API that can be used in syscall HID-BPF programs or in sleepable HID-BPF struct_ops programs:”h]”hŒgAvailable API that can be used in syscall HID-BPF programs or in sleepable HID-BPF struct_ops programs:”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjuh1hÍhjQh²hh³hÇh´KÊubj2 )�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j> Œ%hid_bpf_allocate_context (C function)”Œc.hid_bpf_allocate_context”hNt”auh1j1 hjQh²hh³Nh´NubjC )�”}”(hhh]”(jH )�”}”(hŒO__bpf_kfunc struct hid_bpf_ctx * hid_bpf_allocate_context (unsigned int hid_id)”h]”jN )�”}”(hŒM__bpf_kfunc struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id)”h]”(hŒ __bpf_kfunc”…”�”}”(hjwh²hh³Nh´Nubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjwh²hh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M8ubjT )�”}”(hjW h]”hŒstruct”…”�”}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjwh²hh³j�h´M8ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj›h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjwh²hh³j�h´M8ubh)�”}”(hhh]”j} )�”}”(hŒ hid_bpf_ctx”h]”hŒ hid_bpf_ctx”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj©ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”j®Œmodname”NŒ classname”NjT jW )�”}”jZ ]”jo)�”}”jgŒhid_bpf_allocate_context”sbŒc.hid_bpf_allocate_context”†”asbuh1hhjwh²hh³j�h´M8ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjwh²hh³j�h´M8ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhjwh²hh³j�h´M8ubjw )�”}”(hŒhid_bpf_allocate_context”h]”j} )�”}”(hjÊh]”hŒhid_bpf_allocate_context”…”�”}”(hjìh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjèubah}”(h]”h ]”(j� j� eh"]”h$]”h&]”hÅhÆuh1jv hjwh²hh³j�h´M8ubj¬)�”}”(hŒ(unsigned int hid_id)”h]”j²)�”}”(hŒunsigned int hid_id”h]”(j()�”}”(hŒunsigned”h]”hŒunsigned”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”j4ah"]”h$]”h&]”uh1j'hjubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjubj()�”}”(hŒint”h]”hŒint”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”j4ah"]”h$]”h&]”uh1j'hjubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjubj} )�”}”(hŒhid_id”h]”hŒhid_id”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjÿubah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j«hjwh²hh³j�h´M8ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjš ˆuh1jM j› jœ hjsh²hh³j�h´M8ubah}”(h]”jnah ]”(j  j¡ eh"]”h$]”h&]”j¥ ˆj¦ )j§ huh1jG h³j�h´M8hjph²hubj© )�”}”(hhh]”hÞ)�”}”(hŒ*Allocate a context to the given HID device”h]”hŒ*Allocate a context to the given HID device”…”�”}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M8hjfh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hjph²hh³j�h´M8ubeh}”(h]”h ]”(jÅ Œfunction”eh"]”h$]”h&]”jÊ jÅ jË j�jÌ j�jÍ ‰jÎ ‰jÏ ‰uh1jB h²hhjQh³Nh´NubjÑ )�”}”(hŒÍ**Parameters** ``unsigned int hid_id`` the system unique identifier of the HID device **Description** **returns** A pointer to :c:type:`struct hid_bpf_ctx ` on success, ``NULL`` on error.”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jÛ )�”}”(hj‹h]”hŒ Parameters”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj‰ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M<hj…ubj )�”}”(hhh]”j$ )�”}”(hŒG``unsigned int hid_id`` the system unique identifier of the HID device ”h]”(j* )�”}”(hŒ``unsigned int hid_id``”h]”j")�”}”(hjªh]”hŒunsigned int hid_id”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¨ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M:hj¤ubjD )�”}”(hhh]”hÞ)�”}”(hŒ.the system unique identifier of the HID device”h]”hŒ.the system unique identifier of the HID device”…”�”}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j¿h´M:hjÀubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj¤ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j¿h´M:hj¡ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj…ubhÞ)�”}”(hŒ**Description**”h]”jÛ )�”}”(hjåh]”hŒ Description”…”�”}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjãubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M<hj…ubhÞ)�”}”(hŒb**returns** A pointer to :c:type:`struct hid_bpf_ctx ` on success, ``NULL`` on error.”h]”(jÛ )�”}”(hŒ **returns**”h]”hŒreturns”…”�”}”(hjÿh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjûubhŒ A pointer to ”…”�”}”(hjûh²hh³Nh´Nubh)�”}”(hŒ*:c:type:`struct hid_bpf_ctx `”h]”j")�”}”(hjh]”hŒstruct hid_bpf_ctx”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-type”eh"]”h$]”h&]”uh1j!hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jT jX j\ Œ hid_bpf_ctx”uh1hh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M;hjûubhŒ on success, ”…”�”}”(hjûh²hh³Nh´Nubj")�”}”(hŒ``NULL``”h]”hŒNULL”…”�”}”(hj5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjûubhŒ on error.”…”�”}”(hjûh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j0h´M;hj…ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hjQh²hh³Nh´Nubj2 )�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j> Œ$hid_bpf_release_context (C function)”Œc.hid_bpf_release_context”hNt”auh1j1 hjQh²hh³Nh´NubjC )�”}”(hhh]”(jH )�”}”(hŒB__bpf_kfunc void hid_bpf_release_context (struct hid_bpf_ctx *ctx)”h]”jN )�”}”(hŒA__bpf_kfunc void hid_bpf_release_context(struct hid_bpf_ctx *ctx)”h]”(hŒ __bpf_kfunc”…”�”}”(hjih²hh³Nh´Nubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjqh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjih²hh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MTubj()�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hj€h²hh³Nh´Nubah}”(h]”h ]”j4ah"]”h$]”h&]”uh1j'hjih²hh³jh´MTubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjih²hh³jh´MTubjw )�”}”(hŒhid_bpf_release_context”h]”j} )�”}”(hŒhid_bpf_release_context”h]”hŒhid_bpf_release_context”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjœubah}”(h]”h ]”(j� j� eh"]”h$]”h&]”hÅhÆuh1jv hjih²hh³jh´MTubj¬)�”}”(hŒ(struct hid_bpf_ctx *ctx)”h]”j²)�”}”(hŒstruct hid_bpf_ctx *ctx”h]”(jT )�”}”(hjW h]”hŒstruct”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hj¸ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj¸ubh)�”}”(hhh]”j} )�”}”(hŒ hid_bpf_ctx”h]”hŒ hid_bpf_ctx”…”�”}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj×ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jÜŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jo)�”}”jgj¢sbŒc.hid_bpf_release_context”†”asbuh1hhj¸ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjúh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj¸ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhj¸ubj} )�”}”(hŒctx”h]”hŒctx”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj¸ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj´ubah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j«hjih²hh³jh´MTubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjš ˆuh1jM j› jœ hjeh²hh³jh´MTubah}”(h]”j`ah ]”(j  j¡ eh"]”h$]”h&]”j¥ ˆj¦ )j§ huh1jG h³jh´MThjbh²hubj© )�”}”(hhh]”hÞ)�”}”(hŒ0Release the previously allocated context **ctx**”h]”(hŒ)Release the previously allocated context ”…”�”}”(hj?h²hh³Nh´NubjÛ )�”}”(hŒ**ctx**”h]”hŒctx”…”�”}”(hjGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj?ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MThj<h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hjbh²hh³jh´MTubeh}”(h]”h ]”(jÅ Œfunction”eh"]”h$]”h&]”jÊ jÅ jË jejÌ jejÍ ‰jÎ ‰jÏ ‰uh1jB h²hhjQh³Nh´NubjÑ )�”}”(hŒL**Parameters** ``struct hid_bpf_ctx *ctx`` the HID-BPF context to release”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jÛ )�”}”(hjoh]”hŒ Parameters”…”�”}”(hjqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjmubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MXhjiubj )�”}”(hhh]”j$ )�”}”(hŒ:``struct hid_bpf_ctx *ctx`` the HID-BPF context to release”h]”(j* )�”}”(hŒ``struct hid_bpf_ctx *ctx``”h]”j")�”}”(hjŽh]”hŒstruct hid_bpf_ctx *ctx”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjŒubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MZhjˆubjD )�”}”(hhh]”hÞ)�”}”(hŒthe HID-BPF context to release”h]”hŒthe HID-BPF context to release”…”�”}”(hj§h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MVhj¤ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjˆubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j£h´MZhj…ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjiubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hjQh²hh³Nh´Nubj2 )�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j> Œhid_bpf_hw_request (C function)”Œc.hid_bpf_hw_request”hNt”auh1j1 hjQh²hh³Nh´NubjC )�”}”(hhh]”(jH )�”}”(hŒ“__bpf_kfunc int hid_bpf_hw_request (struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, enum hid_report_type rtype, enum hid_class_request reqtype)”h]”jN )�”}”(hŒ’__bpf_kfunc int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, enum hid_report_type rtype, enum hid_class_request reqtype)”h]”(hŒ __bpf_kfunc”…”�”}”(hjäh²hh³Nh´Nubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjìh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjäh²hh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M’ubj()�”}”(hŒint”h]”hŒint”…”�”}”(hjûh²hh³Nh´Nubah}”(h]”h ]”j4ah"]”h$]”h&]”uh1j'hjäh²hh³júh´M’ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjäh²hh³júh´M’ubjw )�”}”(hŒhid_bpf_hw_request”h]”j} )�”}”(hŒhid_bpf_hw_request”h]”hŒhid_bpf_hw_request”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjubah}”(h]”h ]”(j� j� eh"]”h$]”h&]”hÅhÆuh1jv hjäh²hh³júh´M’ubj¬)�”}”(hŒp(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, enum hid_report_type rtype, enum hid_class_request reqtype)”h]”(j²)�”}”(hŒstruct hid_bpf_ctx *ctx”h]”(jT )�”}”(hjW h]”hŒstruct”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hj3ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjDh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj3ubh)�”}”(hhh]”j} )�”}”(hŒ hid_bpf_ctx”h]”hŒ hid_bpf_ctx”…”�”}”(hjUh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjRubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jWŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jo)�”}”jgjsbŒc.hid_bpf_hw_request”†”asbuh1hhj3ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjuh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj3ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhj3ubj} )�”}”(hŒctx”h]”hŒctx”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj3ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj/ubj²)�”}”(hŒ __u8 *buf”h]”(h)�”}”(hhh]”j} )�”}”(hŒ__u8”h]”hŒ__u8”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj©ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”j®Œmodname”NŒ classname”NjT jW )�”}”jZ ]”jqŒc.hid_bpf_hw_request”†”asbuh1hhj¥ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj¥ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhj¥ubj} )�”}”(hŒbuf”h]”hŒbuf”…”�”}”(hjåh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj¥ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj/ubj²)�”}”(hŒsize_t buf__sz”h]”(h)�”}”(hhh]”j} )�”}”(hŒsize_t”h]”hŒsize_t”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjþubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jqŒc.hid_bpf_hw_request”†”asbuh1hhjúubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjúubj} )�”}”(hŒbuf__sz”h]”hŒbuf__sz”…”�”}”(hj-h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjúubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj/ubj²)�”}”(hŒenum hid_report_type rtype”h]”(jT )�”}”(hŒenum”h]”hŒenum”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjBubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjBubh)�”}”(hhh]”j} )�”}”(hŒhid_report_type”h]”hŒhid_report_type”…”�”}”(hjeh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjbubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jgŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jqŒc.hid_bpf_hw_request”†”asbuh1hhjBubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjƒh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjBubj} )�”}”(hŒrtype”h]”hŒrtype”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjBubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj/ubj²)�”}”(hŒenum hid_class_request reqtype”h]”(jT )�”}”(hjHh]”hŒenum”…”�”}”(hjªh²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hj¦ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj·h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj¦ubh)�”}”(hhh]”j} )�”}”(hŒhid_class_request”h]”hŒhid_class_request”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjÅubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jÊŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jqŒc.hid_bpf_hw_request”†”asbuh1hhj¦ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjæh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj¦ubj} )�”}”(hŒreqtype”h]”hŒreqtype”…”�”}”(hjôh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj¦ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj/ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j«hjäh²hh³júh´M’ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjš ˆuh1jM j› jœ hjàh²hh³júh´M’ubah}”(h]”jÛah ]”(j  j¡ eh"]”h$]”h&]”j¥ ˆj¦ )j§ huh1jG h³júh´M’hjÝh²hubj© )�”}”(hhh]”hÞ)�”}”(hŒCommunicate with a HID device”h]”hŒCommunicate with a HID device”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M’hjh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hjÝh²hh³júh´M’ubeh}”(h]”h ]”(jÅ Œfunction”eh"]”h$]”h&]”jÊ jÅ jË j6jÌ j6jÍ ‰jÎ ‰jÏ ‰uh1jB h²hhjQh³Nh´NubjÑ )�”}”(hX**Parameters** ``struct hid_bpf_ctx *ctx`` the HID-BPF context previously allocated in hid_bpf_allocate_context() ``__u8 *buf`` a ``PTR_TO_MEM`` buffer ``size_t buf__sz`` the size of the data to transfer ``enum hid_report_type rtype`` the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``) ``enum hid_class_request reqtype`` the type of the request (``HID_REQ_GET_REPORT``, ``HID_REQ_SET_REPORT``, ...) **Description** **returns** ``0`` on success, a negative error code otherwise.”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jÛ )�”}”(hj@h]”hŒ Parameters”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj>ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M–hj:ubj )�”}”(hhh]”(j$ )�”}”(hŒc``struct hid_bpf_ctx *ctx`` the HID-BPF context previously allocated in hid_bpf_allocate_context() ”h]”(j* )�”}”(hŒ``struct hid_bpf_ctx *ctx``”h]”j")�”}”(hj_h]”hŒstruct hid_bpf_ctx *ctx”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj]ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M”hjYubjD )�”}”(hhh]”hÞ)�”}”(hŒFthe HID-BPF context previously allocated in hid_bpf_allocate_context()”h]”hŒFthe HID-BPF context previously allocated in hid_bpf_allocate_context()”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jth´M”hjuubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjYubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jth´M”hjVubj$ )�”}”(hŒ&``__u8 *buf`` a ``PTR_TO_MEM`` buffer ”h]”(j* )�”}”(hŒ ``__u8 *buf``”h]”j")�”}”(hj˜h]”hŒ __u8 *buf”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj–ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M•hj’ubjD )�”}”(hhh]”hÞ)�”}”(hŒa ``PTR_TO_MEM`` buffer”h]”(hŒa ”…”�”}”(hj±h²hh³Nh´Nubj")�”}”(hŒ``PTR_TO_MEM``”h]”hŒ PTR_TO_MEM”…”�”}”(hj¹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj±ubhŒ buffer”…”�”}”(hj±h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j­h´M•hj®ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj’ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j­h´M•hjVubj$ )�”}”(hŒ4``size_t buf__sz`` the size of the data to transfer ”h]”(j* )�”}”(hŒ``size_t buf__sz``”h]”j")�”}”(hjãh]”hŒsize_t buf__sz”…”�”}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjáubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M–hjÝubjD )�”}”(hhh]”hÞ)�”}”(hŒ the size of the data to transfer”h]”hŒ the size of the data to transfer”…”�”}”(hjüh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jøh´M–hjùubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjÝubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jøh´M–hjVubj$ )�”}”(hŒ|``enum hid_report_type rtype`` the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``) ”h]”(j* )�”}”(hŒ``enum hid_report_type rtype``”h]”j")�”}”(hjh]”hŒenum hid_report_type rtype”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M—hjubjD )�”}”(hhh]”hÞ)�”}”(hŒ\the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``)”h]”(hŒthe type of the report (”…”�”}”(hj5h²hh³Nh´Nubj")�”}”(hŒ``HID_INPUT_REPORT``”h]”hŒHID_INPUT_REPORT”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj5ubhŒ, ”…”�”}”(hj5h²hh³Nh´Nubj")�”}”(hŒ``HID_FEATURE_REPORT``”h]”hŒHID_FEATURE_REPORT”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj5ubhŒ, ”…”�”}”hj5sbj")�”}”(hŒ``HID_OUTPUT_REPORT``”h]”hŒHID_OUTPUT_REPORT”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj5ubhŒ)”…”�”}”(hj5h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j1h´M—hj2ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j1h´M—hjVubj$ )�”}”(hŒq``enum hid_class_request reqtype`` the type of the request (``HID_REQ_GET_REPORT``, ``HID_REQ_SET_REPORT``, ...) ”h]”(j* )�”}”(hŒ"``enum hid_class_request reqtype``”h]”j")�”}”(hj‹h]”hŒenum hid_class_request reqtype”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj‰ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M˜hj…ubjD )�”}”(hhh]”hÞ)�”}”(hŒMthe type of the request (``HID_REQ_GET_REPORT``, ``HID_REQ_SET_REPORT``, ...)”h]”(hŒthe type of the request (”…”�”}”(hj¤h²hh³Nh´Nubj")�”}”(hŒ``HID_REQ_GET_REPORT``”h]”hŒHID_REQ_GET_REPORT”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¤ubhŒ, ”…”�”}”(hj¤h²hh³Nh´Nubj")�”}”(hŒ``HID_REQ_SET_REPORT``”h]”hŒHID_REQ_SET_REPORT”…”�”}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¤ubhŒ, ...)”…”�”}”(hj¤h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j h´M˜hj¡ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj…ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j h´M˜hjVubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj:ubhÞ)�”}”(hŒ**Description**”h]”jÛ )�”}”(hjêh]”hŒ Description”…”�”}”(hjìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjèubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´Mšhj:ubhÞ)�”}”(hŒ>**returns** ``0`` on success, a negative error code otherwise.”h]”(jÛ )�”}”(hŒ **returns**”h]”hŒreturns”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjubhŒ ”…”�”}”(hjh²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubhŒ- on success, a negative error code otherwise.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M™hj:ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hjQh²hh³Nh´Nubj2 )�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j> Œ%hid_bpf_hw_output_report (C function)”Œc.hid_bpf_hw_output_report”hNt”auh1j1 hjQh²hh³Nh´NubjC )�”}”(hhh]”(jH )�”}”(hŒ]__bpf_kfunc int hid_bpf_hw_output_report (struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)”h]”jN )�”}”(hŒ\__bpf_kfunc int hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)”h]”(hŒ __bpf_kfunc”…”�”}”(hjKh²hh³Nh´Nubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjKh²hh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MÒubj()�”}”(hŒint”h]”hŒint”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”j4ah"]”h$]”h&]”uh1j'hjKh²hh³jah´MÒubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjKh²hh³jah´MÒubjw )�”}”(hŒhid_bpf_hw_output_report”h]”j} )�”}”(hŒhid_bpf_hw_output_report”h]”hŒhid_bpf_hw_output_report”…”�”}”(hj‚h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj~ubah}”(h]”h ]”(j� j� eh"]”h$]”h&]”hÅhÆuh1jv hjKh²hh³jah´MÒubj¬)�”}”(hŒ4(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)”h]”(j²)�”}”(hŒstruct hid_bpf_ctx *ctx”h]”(jT )�”}”(hjW h]”hŒstruct”…”�”}”(hjžh²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjšubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj«h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjšubh)�”}”(hhh]”j} )�”}”(hŒ hid_bpf_ctx”h]”hŒ hid_bpf_ctx”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj¹ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”j¾Œmodname”NŒ classname”NjT jW )�”}”jZ ]”jo)�”}”jgj„sbŒc.hid_bpf_hw_output_report”†”asbuh1hhjšubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjšubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjêh²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhjšubj} )�”}”(hŒctx”h]”hŒctx”…”�”}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjšubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj–ubj²)�”}”(hŒ __u8 *buf”h]”(h)�”}”(hhh]”j} )�”}”(hŒ__u8”h]”hŒ__u8”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jØŒc.hid_bpf_hw_output_report”†”asbuh1hhj ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhj ubj} )�”}”(hŒbuf”h]”hŒbuf”…”�”}”(hjLh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj–ubj²)�”}”(hŒsize_t buf__sz”h]”(h)�”}”(hhh]”j} )�”}”(hŒsize_t”h]”hŒsize_t”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjeubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jjŒmodname”NŒ classname”NjT jW )�”}”jZ ]”jØŒc.hid_bpf_hw_output_report”†”asbuh1hhjaubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj†h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjaubj} )�”}”(hŒbuf__sz”h]”hŒbuf__sz”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjaubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hj–ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j«hjKh²hh³jah´MÒubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjš ˆuh1jM j› jœ hjGh²hh³jah´MÒubah}”(h]”jBah ]”(j  j¡ eh"]”h$]”h&]”j¥ ˆj¦ )j§ huh1jG h³jah´MÒhjDh²hubj© )�”}”(hhh]”hÞ)�”}”(hŒ%Send an output report to a HID device”h]”hŒ%Send an output report to a HID device”…”�”}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MÒhj»h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hjDh²hh³jah´MÒubeh}”(h]”h ]”(jÅ Œfunction”eh"]”h$]”h&]”jÊ jÅ jË jÖjÌ jÖjÍ ‰jÎ ‰jÏ ‰uh1jB h²hhjQh³Nh´NubjÑ )�”}”(hX;**Parameters** ``struct hid_bpf_ctx *ctx`` the HID-BPF context previously allocated in hid_bpf_allocate_context() ``__u8 *buf`` a ``PTR_TO_MEM`` buffer ``size_t buf__sz`` the size of the data to transfer **Description** Returns the number of bytes transferred on success, a negative error code otherwise.”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jÛ )�”}”(hjàh]”hŒ Parameters”…”�”}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjÞubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MÖhjÚubj )�”}”(hhh]”(j$ )�”}”(hŒc``struct hid_bpf_ctx *ctx`` the HID-BPF context previously allocated in hid_bpf_allocate_context() ”h]”(j* )�”}”(hŒ``struct hid_bpf_ctx *ctx``”h]”j")�”}”(hjÿh]”hŒstruct hid_bpf_ctx *ctx”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjýubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MÔhjùubjD )�”}”(hhh]”hÞ)�”}”(hŒFthe HID-BPF context previously allocated in hid_bpf_allocate_context()”h]”hŒFthe HID-BPF context previously allocated in hid_bpf_allocate_context()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jh´MÔhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjùubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jh´MÔhjöubj$ )�”}”(hŒ&``__u8 *buf`` a ``PTR_TO_MEM`` buffer ”h]”(j* )�”}”(hŒ ``__u8 *buf``”h]”j")�”}”(hj8h]”hŒ __u8 *buf”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj6ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MÕhj2ubjD )�”}”(hhh]”hÞ)�”}”(hŒa ``PTR_TO_MEM`` buffer”h]”(hŒa ”…”�”}”(hjQh²hh³Nh´Nubj")�”}”(hŒ``PTR_TO_MEM``”h]”hŒ PTR_TO_MEM”…”�”}”(hjYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjQubhŒ buffer”…”�”}”(hjQh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jMh´MÕhjNubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj2ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jMh´MÕhjöubj$ )�”}”(hŒ4``size_t buf__sz`` the size of the data to transfer ”h]”(j* )�”}”(hŒ``size_t buf__sz``”h]”j")�”}”(hjƒh]”hŒsize_t buf__sz”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MÖhj}ubjD )�”}”(hhh]”hÞ)�”}”(hŒ the size of the data to transfer”h]”hŒ the size of the data to transfer”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j˜h´MÖhj™ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj}ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j˜h´MÖhjöubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hjÚubhÞ)�”}”(hŒ**Description**”h]”jÛ )�”}”(hj¾h]”hŒ Description”…”�”}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj¼ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MØhjÚubhÞ)�”}”(hŒTReturns the number of bytes transferred on success, a negative error code otherwise.”h]”hŒTReturns the number of bytes transferred on success, a negative error code otherwise.”…”�”}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M×hjÚubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hjQh²hh³Nh´Nubj2 )�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j> Œ%hid_bpf_try_input_report (C function)”Œc.hid_bpf_try_input_report”hNt”auh1j1 hjQh²hh³Nh´NubjC )�”}”(hhh]”(jH )�”}”(hŒ|__bpf_kfunc int hid_bpf_try_input_report (struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, const size_t buf__sz)”h]”jN )�”}”(hŒ{__bpf_kfunc int hid_bpf_try_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, const size_t buf__sz)”h]”(hŒ __bpf_kfunc”…”�”}”(hjÿh²hh³Nh´Nubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjÿh²hh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M ubj()�”}”(hŒint”h]”hŒint”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”j4ah"]”h$]”h&]”uh1j'hjÿh²hh³j h´M ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj$ h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjÿh²hh³j h´M ubjw )�”}”(hŒhid_bpf_try_input_report”h]”j} )�”}”(hŒhid_bpf_try_input_report”h]”hŒhid_bpf_try_input_report”…”�”}”(hj6 h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj2 ubah}”(h]”h ]”(j� j� eh"]”h$]”h&]”hÅhÆuh1jv hjÿh²hh³j h´M ubj¬)�”}”(hŒS(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, const size_t buf__sz)”h]”(j²)�”}”(hŒstruct hid_bpf_ctx *ctx”h]”(jT )�”}”(hjW h]”hŒstruct”…”�”}”(hjR h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjN ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj_ h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjN ubh)�”}”(hhh]”j} )�”}”(hŒ hid_bpf_ctx”h]”hŒ hid_bpf_ctx”…”�”}”(hjp h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjm ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jr Œmodname”NŒ classname”NjT jW )�”}”jZ ]”jo)�”}”jgj8 sbŒc.hid_bpf_try_input_report”†”asbuh1hhjN ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjN ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjž h²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhjN ubj} )�”}”(hŒctx”h]”hŒctx”…”�”}”(hj« h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjN ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjJ ubj²)�”}”(hŒenum hid_report_type type”h]”(jT )�”}”(hjHh]”hŒenum”…”�”}”(hjÄ h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjÀ ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÑ h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjÀ ubh)�”}”(hhh]”j} )�”}”(hŒhid_report_type”h]”hŒhid_report_type”…”�”}”(hjâ h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjß ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jä Œmodname”NŒ classname”NjT jW )�”}”jZ ]”jŒ Œc.hid_bpf_try_input_report”†”asbuh1hhjÀ ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj!h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjÀ ubj} )�”}”(hŒtype”h]”hŒtype”…”�”}”(hj!h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjÀ ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjJ ubj²)�”}”(hŒu8 *buf”h]”(h)�”}”(hhh]”j} )�”}”(hŒu8”h]”hŒu8”…”�”}”(hj*!h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj'!ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”j,!Œmodname”NŒ classname”NjT jW )�”}”jZ ]”jŒ Œc.hid_bpf_try_input_report”†”asbuh1hhj#!ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjH!h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj#!ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjV!h²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhj#!ubj} )�”}”(hŒbuf”h]”hŒbuf”…”�”}”(hjc!h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj#!ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjJ ubj²)�”}”(hŒconst size_t buf__sz”h]”(jT )�”}”(hj}h]”hŒconst”…”�”}”(hj|!h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjx!ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‰!h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjx!ubh)�”}”(hhh]”j} )�”}”(hŒsize_t”h]”hŒsize_t”…”�”}”(hjš!h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj—!ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jœ!Œmodname”NŒ classname”NjT jW )�”}”jZ ]”jŒ Œc.hid_bpf_try_input_report”†”asbuh1hhjx!ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¸!h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjx!ubj} )�”}”(hŒbuf__sz”h]”hŒbuf__sz”…”�”}”(hjÆ!h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjx!ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjJ ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j«hjÿh²hh³j h´M ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjš ˆuh1jM j› jœ hjûh²hh³j h´M ubah}”(h]”jöah ]”(j  j¡ eh"]”h$]”h&]”j¥ ˆj¦ )j§ huh1jG h³j h´M hjøh²hubj© )�”}”(hhh]”hÞ)�”}”(hŒ3Inject a HID report in the kernel from a HID device”h]”hŒ3Inject a HID report in the kernel from a HID device”…”�”}”(hjð!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M hjí!h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hjøh²hh³j h´M ubeh}”(h]”h ]”(jÅ Œfunction”eh"]”h$]”h&]”jÊ jÅ jË j"jÌ j"jÍ ‰jÎ ‰jÏ ‰uh1jB h²hhjQh³Nh´NubjÑ )�”}”(hX**Parameters** ``struct hid_bpf_ctx *ctx`` the HID-BPF context previously allocated in hid_bpf_allocate_context() ``enum hid_report_type type`` the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``) ``u8 *buf`` a ``PTR_TO_MEM`` buffer ``const size_t buf__sz`` the size of the data to transfer **Description** Returns ``0`` on success, a negative error code otherwise. This function will immediately fail if the device is not available, thus can be safely used in IRQ context.”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jÛ )�”}”(hj"h]”hŒ Parameters”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj"ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´Mhj "ubj )�”}”(hhh]”(j$ )�”}”(hŒc``struct hid_bpf_ctx *ctx`` the HID-BPF context previously allocated in hid_bpf_allocate_context() ”h]”(j* )�”}”(hŒ``struct hid_bpf_ctx *ctx``”h]”j")�”}”(hj1"h]”hŒstruct hid_bpf_ctx *ctx”…”�”}”(hj3"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj/"ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M hj+"ubjD )�”}”(hhh]”hÞ)�”}”(hŒFthe HID-BPF context previously allocated in hid_bpf_allocate_context()”h]”hŒFthe HID-BPF context previously allocated in hid_bpf_allocate_context()”…”�”}”(hjJ"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jF"h´M hjG"ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj+"ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jF"h´M hj("ubj$ )�”}”(hŒ{``enum hid_report_type type`` the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``) ”h]”(j* )�”}”(hŒ``enum hid_report_type type``”h]”j")�”}”(hjj"h]”hŒenum hid_report_type type”…”�”}”(hjl"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjh"ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M hjd"ubjD )�”}”(hhh]”hÞ)�”}”(hŒ\the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``)”h]”(hŒthe type of the report (”…”�”}”(hjƒ"h²hh³Nh´Nubj")�”}”(hŒ``HID_INPUT_REPORT``”h]”hŒHID_INPUT_REPORT”…”�”}”(hj‹"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjƒ"ubhŒ, ”…”�”}”(hjƒ"h²hh³Nh´Nubj")�”}”(hŒ``HID_FEATURE_REPORT``”h]”hŒHID_FEATURE_REPORT”…”�”}”(hj�"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjƒ"ubhŒ, ”…”�”}”hjƒ"sbj")�”}”(hŒ``HID_OUTPUT_REPORT``”h]”hŒHID_OUTPUT_REPORT”…”�”}”(hj¯"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjƒ"ubhŒ)”…”�”}”(hjƒ"h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j"h´M hj€"ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjd"ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j"h´M hj("ubj$ )�”}”(hŒ$``u8 *buf`` a ``PTR_TO_MEM`` buffer ”h]”(j* )�”}”(hŒ ``u8 *buf``”h]”j")�”}”(hjÙ"h]”hŒu8 *buf”…”�”}”(hjÛ"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj×"ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´MhjÓ"ubjD )�”}”(hhh]”hÞ)�”}”(hŒa ``PTR_TO_MEM`` buffer”h]”(hŒa ”…”�”}”(hjò"h²hh³Nh´Nubj")�”}”(hŒ``PTR_TO_MEM``”h]”hŒ PTR_TO_MEM”…”�”}”(hjú"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjò"ubhŒ buffer”…”�”}”(hjò"h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jî"h´Mhjï"ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjÓ"ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jî"h´Mhj("ubj$ )�”}”(hŒ:``const size_t buf__sz`` the size of the data to transfer ”h]”(j* )�”}”(hŒ``const size_t buf__sz``”h]”j")�”}”(hj$#h]”hŒconst size_t buf__sz”…”�”}”(hj&#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj"#ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´Mhj#ubjD )�”}”(hhh]”hÞ)�”}”(hŒ the size of the data to transfer”h]”hŒ the size of the data to transfer”…”�”}”(hj=#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j9#h´Mhj:#ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj#ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j9#h´Mhj("ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj "ubhÞ)�”}”(hŒ**Description**”h]”jÛ )�”}”(hj_#h]”hŒ Description”…”�”}”(hja#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj]#ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´Mhj "ubhÞ)�”}”(hŒ¦Returns ``0`` on success, a negative error code otherwise. This function will immediately fail if the device is not available, thus can be safely used in IRQ context.”h]”(hŒReturns ”…”�”}”(hju#h²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hj}#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hju#ubhŒ™ on success, a negative error code otherwise. This function will immediately fail if the device is not available, thus can be safely used in IRQ context.”…”�”}”(hju#h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´Mhj "ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hjQh²hh³Nh´Nubj2 )�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j> Œ!hid_bpf_input_report (C function)”Œc.hid_bpf_input_report”hNt”auh1j1 hjQh²hh³Nh´NubjC )�”}”(hhh]”(jH )�”}”(hŒx__bpf_kfunc int hid_bpf_input_report (struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, const size_t buf__sz)”h]”jN )�”}”(hŒw__bpf_kfunc int hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, const size_t buf__sz)”h]”(hŒ __bpf_kfunc”…”�”}”(hj²#h²hh³Nh´Nubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjº#h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj²#h²hh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M"ubj()�”}”(hŒint”h]”hŒint”…”�”}”(hjÉ#h²hh³Nh´Nubah}”(h]”h ]”j4ah"]”h$]”h&]”uh1j'hj²#h²hh³jÈ#h´M"ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj×#h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj²#h²hh³jÈ#h´M"ubjw )�”}”(hŒhid_bpf_input_report”h]”j} )�”}”(hŒhid_bpf_input_report”h]”hŒhid_bpf_input_report”…”�”}”(hjé#h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjå#ubah}”(h]”h ]”(j� j� eh"]”h$]”h&]”hÅhÆuh1jv hj²#h²hh³jÈ#h´M"ubj¬)�”}”(hŒS(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, const size_t buf__sz)”h]”(j²)�”}”(hŒstruct hid_bpf_ctx *ctx”h]”(jT )�”}”(hjW h]”hŒstruct”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hj$ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj$ubh)�”}”(hhh]”j} )�”}”(hŒ hid_bpf_ctx”h]”hŒ hid_bpf_ctx”…”�”}”(hj#$h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj $ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”j%$Œmodname”NŒ classname”NjT jW )�”}”jZ ]”jo)�”}”jgjë#sbŒc.hid_bpf_input_report”†”asbuh1hhj$ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjC$h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj$ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hjQ$h²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhj$ubj} )�”}”(hŒctx”h]”hŒctx”…”�”}”(hj^$h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj$ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjý#ubj²)�”}”(hŒenum hid_report_type type”h]”(jT )�”}”(hjHh]”hŒenum”…”�”}”(hjw$h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hjs$ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj„$h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjs$ubh)�”}”(hhh]”j} )�”}”(hŒhid_report_type”h]”hŒhid_report_type”…”�”}”(hj•$h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj’$ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”j—$Œmodname”NŒ classname”NjT jW )�”}”jZ ]”j?$Œc.hid_bpf_input_report”†”asbuh1hhjs$ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj³$h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjs$ubj} )�”}”(hŒtype”h]”hŒtype”…”�”}”(hjÁ$h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjs$ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjý#ubj²)�”}”(hŒu8 *buf”h]”(h)�”}”(hhh]”j} )�”}”(hŒu8”h]”hŒu8”…”�”}”(hjÝ$h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjÚ$ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jß$Œmodname”NŒ classname”NjT jW )�”}”jZ ]”j?$Œc.hid_bpf_input_report”†”asbuh1hhjÖ$ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjû$h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hjÖ$ubj„)�”}”(hj‡h]”hŒ*”…”�”}”(hj %h²hh³Nh´Nubah}”(h]”h ]”j�ah"]”h$]”h&]”uh1jƒhjÖ$ubj} )�”}”(hŒbuf”h]”hŒbuf”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjÖ$ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjý#ubj²)�”}”(hŒconst size_t buf__sz”h]”(jT )�”}”(hj}h]”hŒconst”…”�”}”(hj/%h²hh³Nh´Nubah}”(h]”h ]”j` ah"]”h$]”h&]”uh1jS hj+%ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hj<%h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj+%ubh)�”}”(hhh]”j} )�”}”(hŒsize_t”h]”hŒsize_t”…”�”}”(hjM%h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hjJ%ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jÅ Œreftype”jgŒ reftarget”jO%Œmodname”NŒ classname”NjT jW )�”}”jZ ]”j?$Œc.hid_bpf_input_report”†”asbuh1hhj+%ubjf )�”}”(hŒ ”h]”hŒ ”…”�”}”(hjk%h²hh³Nh´Nubah}”(h]”h ]”jr ah"]”h$]”h&]”uh1je hj+%ubj} )�”}”(hŒbuf__sz”h]”hŒbuf__sz”…”�”}”(hjy%h²hh³Nh´Nubah}”(h]”h ]”jˆ ah"]”h$]”h&]”uh1j| hj+%ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆhÅhÆuh1j±hjý#ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1j«hj²#h²hh³jÈ#h´M"ubeh}”(h]”h ]”h"]”h$]”h&]”hÅhÆjš ˆuh1jM j› jœ hj®#h²hh³jÈ#h´M"ubah}”(h]”j©#ah ]”(j  j¡ eh"]”h$]”h&]”j¥ ˆj¦ )j§ huh1jG h³jÈ#h´M"hj«#h²hubj© )�”}”(hhh]”hÞ)�”}”(hŒ3Inject a HID report in the kernel from a HID device”h]”hŒ3Inject a HID report in the kernel from a HID device”…”�”}”(hj£%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M"hj %h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¨ hj«#h²hh³jÈ#h´M"ubeh}”(h]”h ]”(jÅ Œfunction”eh"]”h$]”h&]”jÊ jÅ jË j»%jÌ j»%jÍ ‰jÎ ‰jÏ ‰uh1jB h²hhjQh³Nh´NubjÑ )�”}”(hX$**Parameters** ``struct hid_bpf_ctx *ctx`` the HID-BPF context previously allocated in hid_bpf_allocate_context() ``enum hid_report_type type`` the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``) ``u8 *buf`` a ``PTR_TO_MEM`` buffer ``const size_t buf__sz`` the size of the data to transfer **Description** Returns ``0`` on success, a negative error code otherwise. This function will wait for the device to be available before injecting the event, thus needs to be called in sleepable context.”h]”(hÞ)�”}”(hŒ**Parameters**”h]”jÛ )�”}”(hjÅ%h]”hŒ Parameters”…”�”}”(hjÇ%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjÃ%ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M&hj¿%ubj )�”}”(hhh]”(j$ )�”}”(hŒc``struct hid_bpf_ctx *ctx`` the HID-BPF context previously allocated in hid_bpf_allocate_context() ”h]”(j* )�”}”(hŒ``struct hid_bpf_ctx *ctx``”h]”j")�”}”(hjä%h]”hŒstruct hid_bpf_ctx *ctx”…”�”}”(hjæ%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjâ%ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M$hjÞ%ubjD )�”}”(hhh]”hÞ)�”}”(hŒFthe HID-BPF context previously allocated in hid_bpf_allocate_context()”h]”hŒFthe HID-BPF context previously allocated in hid_bpf_allocate_context()”…”�”}”(hjý%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jù%h´M$hjú%ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjÞ%ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jù%h´M$hjÛ%ubj$ )�”}”(hŒ{``enum hid_report_type type`` the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``) ”h]”(j* )�”}”(hŒ``enum hid_report_type type``”h]”j")�”}”(hj&h]”hŒenum hid_report_type type”…”�”}”(hj&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M%hj&ubjD )�”}”(hhh]”hÞ)�”}”(hŒ\the type of the report (``HID_INPUT_REPORT``, ``HID_FEATURE_REPORT``, ``HID_OUTPUT_REPORT``)”h]”(hŒthe type of the report (”…”�”}”(hj6&h²hh³Nh´Nubj")�”}”(hŒ``HID_INPUT_REPORT``”h]”hŒHID_INPUT_REPORT”…”�”}”(hj>&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj6&ubhŒ, ”…”�”}”(hj6&h²hh³Nh´Nubj")�”}”(hŒ``HID_FEATURE_REPORT``”h]”hŒHID_FEATURE_REPORT”…”�”}”(hjP&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj6&ubhŒ, ”…”�”}”hj6&sbj")�”}”(hŒ``HID_OUTPUT_REPORT``”h]”hŒHID_OUTPUT_REPORT”…”�”}”(hjb&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj6&ubhŒ)”…”�”}”(hj6&h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j2&h´M%hj3&ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj&ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j2&h´M%hjÛ%ubj$ )�”}”(hŒ$``u8 *buf`` a ``PTR_TO_MEM`` buffer ”h]”(j* )�”}”(hŒ ``u8 *buf``”h]”j")�”}”(hjŒ&h]”hŒu8 *buf”…”�”}”(hjŽ&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjŠ&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M&hj†&ubjD )�”}”(hhh]”hÞ)�”}”(hŒa ``PTR_TO_MEM`` buffer”h]”(hŒa ”…”�”}”(hj¥&h²hh³Nh´Nubj")�”}”(hŒ``PTR_TO_MEM``”h]”hŒ PTR_TO_MEM”…”�”}”(hj­&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¥&ubhŒ buffer”…”�”}”(hj¥&h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³j¡&h´M&hj¢&ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hj†&ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³j¡&h´M&hjÛ%ubj$ )�”}”(hŒ:``const size_t buf__sz`` the size of the data to transfer ”h]”(j* )�”}”(hŒ``const size_t buf__sz``”h]”j")�”}”(hj×&h]”hŒconst size_t buf__sz”…”�”}”(hjÙ&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÕ&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j) h³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M'hjÑ&ubjD )�”}”(hhh]”hÞ)�”}”(hŒ the size of the data to transfer”h]”hŒ the size of the data to transfer”…”�”}”(hjð&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³jì&h´M'hjí&ubah}”(h]”h ]”h"]”h$]”h&]”uh1jC hjÑ&ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j# h³jì&h´M'hjÛ%ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj¿%ubhÞ)�”}”(hŒ**Description**”h]”jÛ )�”}”(hj'h]”hŒ Description”…”�”}”(hj'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hj'ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M)hj¿%ubhÞ)�”}”(hŒ»Returns ``0`` on success, a negative error code otherwise. This function will wait for the device to be available before injecting the event, thus needs to be called in sleepable context.”h]”(hŒReturns ”…”�”}”(hj('h²hh³Nh´Nub•¤j")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hj0'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj('ubhŒ® on success, a negative error code otherwise. This function will wait for the device to be available before injecting the event, thus needs to be called in sleepable context.”…”�”}”(hj('h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³Œ_/var/lib/git/docbuild/linux/Documentation/hid/hid-bpf:204: ./drivers/hid/bpf/hid_bpf_dispatch.c”h´M(hj¿%ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jÐ hjQh²hh³Nh´Nubeh}”(h]”jah ]”h"]”Œgavailable api that can be used in syscall hid-bpf programs or in sleepable hid-bpf struct_ops programs:”ah$]”h&]”uh1hÈhjþh²hh³hÇh´KÊubeh}”(h]”j}ah ]”h"]”Œdeveloper api:”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K´ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ%General overview of a HID-BPF program”h]”hŒ%General overview of a HID-BPF program”…”�”}”(hja'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNj<uh1hÍhj^'h²hh³hÇh´KÐubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ*Accessing the data attached to the context”h]”hŒ*Accessing the data attached to the context”…”�”}”(hjr'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNj[uh1hÍhjo'h²hh³hÇh´KÓubhÞ)�”}”(hŒ–The ``struct hid_bpf_ctx`` doesn't export the ``data`` fields directly and to access it, a bpf program needs to first call :c:func:`hid_bpf_get_data`.”h]”(hŒThe ”…”�”}”(hj€'h²hh³Nh´Nubj")�”}”(hŒ``struct hid_bpf_ctx``”h]”hŒstruct hid_bpf_ctx”…”�”}”(hjˆ'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj€'ubhŒ doesn’t export the ”…”�”}”(hj€'h²hh³Nh´Nubj")�”}”(hŒ``data``”h]”hŒdata”…”�”}”(hjš'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj€'ubhŒE fields directly and to access it, a bpf program needs to first call ”…”�”}”(hj€'h²hh³Nh´Nubh)�”}”(hŒ:c:func:`hid_bpf_get_data`”h]”j")�”}”(hj®'h]”hŒhid_bpf_get_data()”…”�”}”(hj°'h²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-func”eh"]”h$]”h&]”uh1j!hj¬'ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jT jX j\ Œhid_bpf_get_data”uh1hh³hÇh´KÕhj€'ubhŒ.”…”�”}”(hj€'h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÕhjo'h²hubhÞ)�”}”(hŒX``offset`` can be any integer, but ``size`` needs to be constant, known at compile time.”h]”(j")�”}”(hŒ ``offset``”h]”hŒoffset”…”�”}”(hjÙ'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÕ'ubhŒ can be any integer, but ”…”�”}”(hjÕ'h²hh³Nh´Nubj")�”}”(hŒ``size``”h]”hŒsize”…”�”}”(hjë'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÕ'ubhŒ- needs to be constant, known at compile time.”…”�”}”(hjÕ'h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KØhjo'h²hubhÞ)�”}”(hŒThis allows the following:”h]”hŒThis allows the following:”…”�”}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÛhjo'h²hubjÛ)�”}”(hhh]”(hø)�”}”(hXRfor a given device, if we know that the report length will always be of a certain value, we can request the ``data`` pointer to point at the full report length. The kernel will ensure we are using a correct size and offset and eBPF will ensure the code will not attempt to read or write outside of the boundaries:: __u8 *data = hid_bpf_get_data(ctx, 0 /* offset */, 256 /* size */); if (!data) return 0; /* ensure data is correct, now the verifier knows we * have 256 bytes available */ bpf_printk("hello world: %02x %02x %02x", data[0], data[128], data[255]); ”h]”(hÞ)�”}”(hŒ for a given device, if we know that the report length will always be of a certain value, we can request the ``data`` pointer to point at the full report length.”h]”(hŒlfor a given device, if we know that the report length will always be of a certain value, we can request the ”…”�”}”(hj(h²hh³Nh´Nubj")�”}”(hŒ``data``”h]”hŒdata”…”�”}”(hj (h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj(ubhŒ, pointer to point at the full report length.”…”�”}”(hj(h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KÝhj(ubhÞ)�”}”(hŒ™The kernel will ensure we are using a correct size and offset and eBPF will ensure the code will not attempt to read or write outside of the boundaries::”h]”hŒ˜The kernel will ensure we are using a correct size and offset and eBPF will ensure the code will not attempt to read or write outside of the boundaries:”…”�”}”(hj8(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Kàhj(ubjö )�”}”(hX __u8 *data = hid_bpf_get_data(ctx, 0 /* offset */, 256 /* size */); if (!data) return 0; /* ensure data is correct, now the verifier knows we * have 256 bytes available */ bpf_printk("hello world: %02x %02x %02x", data[0], data[128], data[255]);”h]”hX __u8 *data = hid_bpf_get_data(ctx, 0 /* offset */, 256 /* size */); if (!data) return 0; /* ensure data is correct, now the verifier knows we * have 256 bytes available */ bpf_printk("hello world: %02x %02x %02x", data[0], data[128], data[255]);”…”�”}”hjF(sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jõ h³hÇh´Kãhj(ubeh}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj(h²hh³hÇh´Nubhø)�”}”(hX%if the report length is variable, but we know the value of ``X`` is always a 16-bit integer, we can then have a pointer to that value only:: __u16 *x = hid_bpf_get_data(ctx, offset, sizeof(*x)); if (!x) return 0; /* something went wrong */ *x += 1; /* increment X by one */ ”h]”(hÞ)�”}”(hŒŒif the report length is variable, but we know the value of ``X`` is always a 16-bit integer, we can then have a pointer to that value only::”h]”(hŒ;if the report length is variable, but we know the value of ”…”�”}”(hj^(h²hh³Nh´Nubj")�”}”(hŒ``X``”h]”hŒX”…”�”}”(hjf(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj^(ubhŒK is always a 16-bit integer, we can then have a pointer to that value only:”…”�”}”(hj^(h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KëhjZ(ubjö )�”}”(hŒŠ__u16 *x = hid_bpf_get_data(ctx, offset, sizeof(*x)); if (!x) return 0; /* something went wrong */ *x += 1; /* increment X by one */”h]”hŒŠ__u16 *x = hid_bpf_get_data(ctx, offset, sizeof(*x)); if (!x) return 0; /* something went wrong */ *x += 1; /* increment X by one */”…”�”}”hj~(sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jõ h³hÇh´KîhjZ(ubeh}”(h]”h ]”h"]”h$]”h&]”uh1h÷hj(h²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jjjhjjuh1jÚhjo'h²hh³hÇh´KÝubeh}”(h]”jaah ]”h"]”Œ*accessing the data attached to the context”ah$]”h&]”uh1hÈhj^'h²hh³hÇh´KÓubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒEffect of a HID-BPF program”h]”hŒEffect of a HID-BPF program”…”�”}”(hj¢(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNj}uh1hÍhjŸ(h²hh³hÇh´KöubhÞ)�”}”(hX)For all HID-BPF attachment types except for :c:func:`hid_rdesc_fixup`, several eBPF programs can be attached to the same device. If a HID-BPF struct_ops has a :c:func:`hid_rdesc_fixup` while another is already attached to the device, the kernel will return `-EINVAL` when attaching the struct_ops.”h]”(hŒ,For all HID-BPF attachment types except for ”…”�”}”(hj°(h²hh³Nh´Nubh)�”}”(hŒ:c:func:`hid_rdesc_fixup`”h]”j")�”}”(hjº(h]”hŒhid_rdesc_fixup()”…”�”}”(hj¼(h²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-func”eh"]”h$]”h&]”uh1j!hj¸(ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jT jX j\ Œhid_rdesc_fixup”uh1hh³hÇh´Køhj°(ubhŒZ, several eBPF programs can be attached to the same device. If a HID-BPF struct_ops has a ”…”�”}”(hj°(h²hh³Nh´Nubh)�”}”(hŒ:c:func:`hid_rdesc_fixup`”h]”j")�”}”(hjÝ(h]”hŒhid_rdesc_fixup()”…”�”}”(hjß(h²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-func”eh"]”h$]”h&]”uh1j!hjÛ(ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jT jX j\ Œhid_rdesc_fixup”uh1hh³hÇh´Køhj°(ubhŒI while another is already attached to the device, the kernel will return ”…”�”}”(hj°(h²hh³Nh´NubhŒtitle_reference”“”)�”}”(hŒ `-EINVAL`”h]”hŒ-EINVAL”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jþ(hj°(ubhŒ when attaching the struct_ops.”…”�”}”(hj°(h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KøhjŸ(h²hubhÞ)�”}”(hX&Unless ``BPF_F_BEFORE`` is added to the flags while attaching the program, the new program is appended at the end of the list. ``BPF_F_BEFORE`` will insert the new program at the beginning of the list which is useful for e.g. tracing where we need to get the unprocessed events from the device.”h]”(hŒUnless ”…”�”}”(hj)h²hh³Nh´Nubj")�”}”(hŒ``BPF_F_BEFORE``”h]”hŒ BPF_F_BEFORE”…”�”}”(hj )h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj)ubhŒh is added to the flags while attaching the program, the new program is appended at the end of the list. ”…”�”}”(hj)h²hh³Nh´Nubj")�”}”(hŒ``BPF_F_BEFORE``”h]”hŒ BPF_F_BEFORE”…”�”}”(hj2)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj)ubhŒ— will insert the new program at the beginning of the list which is useful for e.g. tracing where we need to get the unprocessed events from the device.”…”�”}”(hj)h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´KýhjŸ(h²hubhÞ)�”}”(hŒŽNote that if there are multiple programs using the ``BPF_F_BEFORE`` flag, only the most recently loaded one is actually the first in the list.”h]”(hŒ3Note that if there are multiple programs using the ”…”�”}”(hjJ)h²hh³Nh´Nubj")�”}”(hŒ``BPF_F_BEFORE``”h]”hŒ BPF_F_BEFORE”…”�”}”(hjR)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjJ)ubhŒK flag, only the most recently loaded one is actually the first in the list.”…”�”}”(hjJ)h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MhjŸ(h²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ&``SEC("struct_ops/hid_device_event")``”h]”j")�”}”(hjo)h]”hŒ"SEC("struct_ops/hid_device_event")”…”�”}”(hjq)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjm)ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjj)h²hh³hÇh´MubhÞ)�”}”(hŒ~Whenever a matching event is raised, the eBPF programs are called one after the other and are working on the same data buffer.”h]”hŒ~Whenever a matching event is raised, the eBPF programs are called one after the other and are working on the same data buffer.”…”�”}”(hj„)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mhjj)h²hubhÞ)�”}”(hŒœIf a program changes the data associated with the context, the next one will see the modified data but it will have *no* idea of what the original data was.”h]”(hŒtIf a program changes the data associated with the context, the next one will see the modified data but it will have ”…”�”}”(hj’)h²hh³Nh´Nubjw)�”}”(hŒ*no*”h]”hŒno”…”�”}”(hjš)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jvhj’)ubhŒ$ idea of what the original data was.”…”�”}”(hj’)h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M hjj)h²hubhÞ)�”}”(hŒÝOnce all the programs are run and return ``0`` or a positive value, the rest of the HID stack will work on the modified data, with the ``size`` field of the last hid_bpf_ctx being the new size of the input stream of data.”h]”(hŒ)Once all the programs are run and return ”…”�”}”(hj²)h²hh³Nh´Nubj")�”}”(hŒ``0``”h]”hŒ0”…”�”}”(hjº)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj²)ubhŒY or a positive value, the rest of the HID stack will work on the modified data, with the ”…”�”}”(hj²)h²hh³Nh´Nubj")�”}”(hŒ``size``”h]”hŒsize”…”�”}”(hjÌ)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj²)ubhŒN field of the last hid_bpf_ctx being the new size of the input stream of data.”…”�”}”(hj²)h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mhjj)h²hubhÞ)�”}”(hŒ¯A BPF program returning a negative error discards the event, i.e. this event will not be processed by the HID stack. Clients (hidraw, input, LEDs) will **not** see this event.”h]”(hŒ˜A BPF program returning a negative error discards the event, i.e. this event will not be processed by the HID stack. Clients (hidraw, input, LEDs) will ”…”�”}”(hjä)h²hh³Nh´NubjÛ )�”}”(hŒ**not**”h]”hŒnot”…”�”}”(hjì)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÚ hjä)ubhŒ see this event.”…”�”}”(hjä)h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mhjj)h²hubeh}”(h]”Œsec-struct-ops-hid-device-event”ah ]”h"]”Œ"sec("struct_ops/hid_device_event")”ah$]”h&]”uh1hÈhjŸ(h²hh³hÇh´MubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ``SEC("syscall")``”h]”j")�”}”(hj*h]”hŒSEC("syscall")”…”�”}”(hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj*ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj *h²hh³hÇh´MubhÞ)�”}”(hŒî``syscall`` are not attached to a given device. To tell which device we are working with, userspace needs to refer to the device by its unique system id (the last 4 numbers in the sysfs path: ``/sys/bus/hid/devices/xxxx:yyyy:zzzz:0000``).”h]”(j")�”}”(hŒ ``syscall``”h]”hŒsyscall”…”�”}”(hj**h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj&*ubhŒµ are not attached to a given device. To tell which device we are working with, userspace needs to refer to the device by its unique system id (the last 4 numbers in the sysfs path: ”…”�”}”(hj&*h²hh³Nh´Nubj")�”}”(hŒ,``/sys/bus/hid/devices/xxxx:yyyy:zzzz:0000``”h]”hŒ(/sys/bus/hid/devices/xxxx:yyyy:zzzz:0000”…”�”}”(hj<*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj&*ubhŒ).”…”�”}”(hj&*h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mhj *h²hubhÞ)�”}”(hXjTo retrieve a context associated with the device, the program must call hid_bpf_allocate_context() and must release it with hid_bpf_release_context() before returning. Once the context is retrieved, one can also request a pointer to kernel memory with hid_bpf_get_data(). This memory is big enough to support all input/output/feature reports of the given device.”h]”hXjTo retrieve a context associated with the device, the program must call hid_bpf_allocate_context() and must release it with hid_bpf_release_context() before returning. Once the context is retrieved, one can also request a pointer to kernel memory with hid_bpf_get_data(). This memory is big enough to support all input/output/feature reports of the given device.”…”�”}”(hjT*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mhj *h²hubeh}”(h]”Œ sec-syscall”ah ]”h"]”Œsec("syscall")”ah$]”h&]”uh1hÈhjŸ(h²hh³hÇh´MubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ%``SEC("struct_ops/hid_rdesc_fixup")``”h]”j")�”}”(hjo*h]”hŒ!SEC("struct_ops/hid_rdesc_fixup")”…”�”}”(hjq*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjm*ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjj*h²hh³hÇh´M$ubhÞ)�”}”(hŒhThe ``hid_rdesc_fixup`` program works in a similar manner to ``.report_fixup`` of ``struct hid_driver``.”h]”(hŒThe ”…”�”}”(hj„*h²hh³Nh´Nubj")�”}”(hŒ``hid_rdesc_fixup``”h]”hŒhid_rdesc_fixup”…”�”}”(hjŒ*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj„*ubhŒ& program works in a similar manner to ”…”�”}”(hj„*h²hh³Nh´Nubj")�”}”(hŒ``.report_fixup``”h]”hŒ .report_fixup”…”�”}”(hjž*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj„*ubhŒ of ”…”�”}”(hj„*h²hh³Nh´Nubj")�”}”(hŒ``struct hid_driver``”h]”hŒstruct hid_driver”…”�”}”(hj°*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj„*ubhŒ.”…”�”}”(hj„*h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M&hjj*h²hubhÞ)�”}”(hŒËWhen the device is probed, the kernel sets the data buffer of the context with the content of the report descriptor. The memory associated with that buffer is ``HID_MAX_DESCRIPTOR_SIZE`` (currently 4kB).”h]”(hŒŸWhen the device is probed, the kernel sets the data buffer of the context with the content of the report descriptor. The memory associated with that buffer is ”…”�”}”(hjÈ*h²hh³Nh´Nubj")�”}”(hŒ``HID_MAX_DESCRIPTOR_SIZE``”h]”hŒHID_MAX_DESCRIPTOR_SIZE”…”�”}”(hjÐ*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjÈ*ubhŒ (currently 4kB).”…”�”}”(hjÈ*h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M)hjj*h²hubhÞ)�”}”(hŒThe eBPF program can modify the data buffer at-will and the kernel uses the modified content and size as the report descriptor.”h]”hŒThe eBPF program can modify the data buffer at-will and the kernel uses the modified content and size as the report descriptor.”…”�”}”(hjè*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M-hjj*h²hubhÞ)�”}”(hŒÇWhenever a struct_ops containing a ``SEC("struct_ops/hid_rdesc_fixup")`` program is attached (if no program was attached before), the kernel immediately disconnects the HID device and does a reprobe.”h]”(hŒ#Whenever a struct_ops containing a ”…”�”}”(hjö*h²hh³Nh´Nubj")�”}”(hŒ%``SEC("struct_ops/hid_rdesc_fixup")``”h]”hŒ!SEC("struct_ops/hid_rdesc_fixup")”…”�”}”(hjþ*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjö*ubhŒ program is attached (if no program was attached before), the kernel immediately disconnects the HID device and does a reprobe.”…”�”}”(hjö*h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M0hjj*h²hubhÞ)�”}”(hŒ`In the same way, when this struct_ops is detached, the kernel issues a disconnect on the device.”h]”hŒ`In the same way, when this struct_ops is detached, the kernel issues a disconnect on the device.”…”�”}”(hj+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M4hjj*h²hubhÞ)�”}”(hX­There is no ``detach`` facility in HID-BPF. Detaching a program happens when all the user space file descriptors pointing at a HID-BPF struct_ops link are closed. Thus, if we need to replace a report descriptor fixup, some cooperation is required from the owner of the original report descriptor fixup. The previous owner will likely pin the struct_ops link in the bpffs, and we can then replace it through normal bpf operations.”h]”(hŒ There is no ”…”�”}”(hj$+h²hh³Nh´Nubj")�”}”(hŒ ``detach``”h]”hŒdetach”…”�”}”(hj,+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj$+ubhX— facility in HID-BPF. Detaching a program happens when all the user space file descriptors pointing at a HID-BPF struct_ops link are closed. Thus, if we need to replace a report descriptor fixup, some cooperation is required from the owner of the original report descriptor fixup. The previous owner will likely pin the struct_ops link in the bpffs, and we can then replace it through normal bpf operations.”…”�”}”(hj$+h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M7hjj*h²hubeh}”(h]”Œsec-struct-ops-hid-rdesc-fixup”ah ]”h"]”Œ!sec("struct_ops/hid_rdesc_fixup")”ah$]”h&]”uh1hÈhjŸ(h²hh³hÇh´M$ubeh}”(h]”jƒah ]”h"]”Œeffect of a hid-bpf program”ah$]”h&]”uh1hÈhj^'h²hh³hÇh´Köubeh}”(h]”jBah ]”h"]”Œ%general overview of a hid-bpf program”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KÐubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ#Attaching a bpf program to a device”h]”hŒ#Attaching a bpf program to a device”…”�”}”(hj]+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNj«uh1hÍhjZ+h²hh³hÇh´M?ubhÞ)�”}”(hŒûWe now use standard struct_ops attachment through ``bpf_map__attach_struct_ops()``. But given that we need to attach a struct_ops to a dedicated HID device, the caller must set ``hid_id`` in the struct_ops map before loading the program in the kernel.”h]”(hŒ2We now use standard struct_ops attachment through ”…”�”}”(hjk+h²hh³Nh´Nubj")�”}”(hŒ ``bpf_map__attach_struct_ops()``”h]”hŒbpf_map__attach_struct_ops()”…”�”}”(hjs+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjk+ubhŒ_. But given that we need to attach a struct_ops to a dedicated HID device, the caller must set ”…”�”}”(hjk+h²hh³Nh´Nubj")�”}”(hŒ ``hid_id``”h]”hŒhid_id”…”�”}”(hj…+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjk+ubhŒ@ in the struct_ops map before loading the program in the kernel.”…”�”}”(hjk+h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MAhjZ+h²hubhÞ)�”}”(hŒ‰``hid_id`` is the unique system ID of the HID device (the last 4 numbers in the sysfs path: ``/sys/bus/hid/devices/xxxx:yyyy:zzzz:0000``)”h]”(j")�”}”(hŒ ``hid_id``”h]”hŒhid_id”…”�”}”(hj¡+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj�+ubhŒR is the unique system ID of the HID device (the last 4 numbers in the sysfs path: ”…”�”}”(hj�+h²hh³Nh´Nubj")�”}”(hŒ,``/sys/bus/hid/devices/xxxx:yyyy:zzzz:0000``”h]”hŒ(/sys/bus/hid/devices/xxxx:yyyy:zzzz:0000”…”�”}”(hj³+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj�+ubhŒ)”…”�”}”(hj�+h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MEhjZ+h²hubhÞ)�”}”(hŒKOne can also set ``flags``, which is of type ``enum hid_bpf_attach_flags``.”h]”(hŒOne can also set ”…”�”}”(hjË+h²hh³Nh´Nubj")�”}”(hŒ ``flags``”h]”hŒflags”…”�”}”(hjÓ+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjË+ubhŒ, which is of type ”…”�”}”(hjË+h²hh³Nh´Nubj")�”}”(hŒ``enum hid_bpf_attach_flags``”h]”hŒenum hid_bpf_attach_flags”…”�”}”(hjå+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjË+ubhŒ.”…”�”}”(hjË+h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MHhjZ+h²hubhÞ)�”}”(hXWe can not rely on hidraw to bind a BPF program to a HID device. hidraw is an artefact of the processing of the HID device, and is not stable. Some drivers even disable it, so that removes the tracing capabilities on those devices (where it is interesting to get the non-hidraw traces).”h]”hXWe can not rely on hidraw to bind a BPF program to a HID device. hidraw is an artefact of the processing of the HID device, and is not stable. Some drivers even disable it, so that removes the tracing capabilities on those devices (where it is interesting to get the non-hidraw traces).”…”�”}”(hjý+h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MJhjZ+h²hubhÞ)�”}”(hŒ{On the other hand, the ``hid_id`` is stable for the entire life of the HID device, even if we change its report descriptor.”h]”(hŒOn the other hand, the ”…”�”}”(hj ,h²hh³Nh´Nubj")�”}”(hŒ ``hid_id``”h]”hŒhid_id”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj ,ubhŒZ is stable for the entire life of the HID device, even if we change its report descriptor.”…”�”}”(hj ,h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MOhjZ+h²hubhÞ)�”}”(hXGiven that hidraw is not stable when the device disconnects/reconnects, we recommend accessing the current report descriptor of the device through the sysfs. This is available at ``/sys/bus/hid/devices/BUS:VID:PID.000N/report_descriptor`` as a binary stream.”h]”(hŒ³Given that hidraw is not stable when the device disconnects/reconnects, we recommend accessing the current report descriptor of the device through the sysfs. This is available at ”…”�”}”(hj+,h²hh³Nh´Nubj")�”}”(hŒ;``/sys/bus/hid/devices/BUS:VID:PID.000N/report_descriptor``”h]”hŒ7/sys/bus/hid/devices/BUS:VID:PID.000N/report_descriptor”…”�”}”(hj3,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj+,ubhŒ as a binary stream.”…”�”}”(hj+,h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MRhjZ+h²hubhÞ)�”}”(hŒ�Parsing the report descriptor is the responsibility of the BPF programmer or the userspace component that loads the eBPF program.”h]”hŒ�Parsing the report descriptor is the responsibility of the BPF programmer or the userspace component that loads the eBPF program.”…”�”}”(hjK,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MWhjZ+h²hubeh}”(h]”j±ah ]”h"]”Œ#attaching a bpf program to a device”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´M?ubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒ9An (almost) complete example of a BPF enhanced HID device”h]”hŒ9An (almost) complete example of a BPF enhanced HID device”…”�”}”(hjc,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjÍuh1hÍhj`,h²hh³hÇh´M[ubhÞ)�”}”(hŒH*Foreword: for most parts, this could be implemented as a kernel driver*”h]”jw)�”}”(hjs,h]”hŒFForeword: for most parts, this could be implemented as a kernel driver”…”�”}”(hju,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jvhjq,ubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M]hj`,h²hubhÞ)�”}”(hXyLet's imagine we have a new tablet device that has some haptic capabilities to simulate the surface the user is scratching on. This device would also have a specific 3 positions switch to toggle between *pencil on paper*, *cray on a wall* and *brush on a painting canvas*. To make things even better, we can control the physical position of the switch through a feature report.”h]”(hŒÍLet’s imagine we have a new tablet device that has some haptic capabilities to simulate the surface the user is scratching on. This device would also have a specific 3 positions switch to toggle between ”…”�”}”(hjˆ,h²hh³Nh´Nubjw)�”}”(hŒ*pencil on paper*”h]”hŒpencil on paper”…”�”}”(hj�,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jvhjˆ,ubhŒ, ”…”�”}”(hjˆ,h²hh³Nh´Nubjw)�”}”(hŒ*cray on a wall*”h]”hŒcray on a wall”…”�”}”(hj¢,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jvhjˆ,ubhŒ and ”…”�”}”(hjˆ,h²hh³Nh´Nubjw)�”}”(hŒ*brush on a painting canvas*”h]”hŒbrush on a painting canvas”…”�”}”(hj´,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jvhjˆ,ubhŒj. To make things even better, we can control the physical position of the switch through a feature report.”…”�”}”(hjˆ,h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M_hj`,h²hubhÞ)�”}”(hŒtAnd of course, the switch is relying on some userspace component to control the haptic feature of the device itself.”h]”hŒtAnd of course, the switch is relying on some userspace component to control the haptic feature of the device itself.”…”�”}”(hjÌ,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´Mehj`,h²hubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒFiltering events”h]”hŒFiltering events”…”�”}”(hjÝ,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjìuh1hÍhjÚ,h²hh³hÇh´MiubhÞ)�”}”(hŒõThe first step consists in filtering events from the device. Given that the switch position is actually reported in the flow of the pen events, using hidraw to implement that filtering would mean that we wake up userspace for every single event.”h]”hŒõThe first step consists in filtering events from the device. Given that the switch position is actually reported in the flow of the pen events, using hidraw to implement that filtering would mean that we wake up userspace for every single event.”…”�”}”(hjë,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MkhjÚ,h²hubhÞ)�”}”(hŒ}This is OK for libinput, but having an external library that is just interested in one byte in the report is less than ideal.”h]”hŒ}This is OK for libinput, but having an external library that is just interested in one byte in the report is less than ideal.”…”�”}”(hjù,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MohjÚ,h²hubhÞ)�”}”(hŒ>For that, we can create a basic skeleton for our BPF program::”h]”hŒ=For that, we can create a basic skeleton for our BPF program:”…”�”}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MrhjÚ,h²hubjö )�”}”(hX#include "vmlinux.h" #include #include /* HID programs need to be GPL */ char _license[] SEC("license") = "GPL"; /* HID-BPF kfunc API definitions */ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t __sz) __ksym; struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 4096 * 64); } ringbuf SEC(".maps"); __u8 current_value = 0; SEC("struct_ops/hid_device_event") int BPF_PROG(filter_switch, struct hid_bpf_ctx *hid_ctx) { __u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 192 /* size */); __u8 *buf; if (!data) return 0; /* EPERM check */ if (current_value != data[152]) { buf = bpf_ringbuf_reserve(&ringbuf, 1, 0); if (!buf) return 0; *buf = data[152]; bpf_ringbuf_commit(buf, 0); current_value = data[152]; } return 0; } SEC(".struct_ops.link") struct hid_bpf_ops haptic_tablet = { .hid_device_event = (void *)filter_switch, };”h]”hX#include "vmlinux.h" #include #include /* HID programs need to be GPL */ char _license[] SEC("license") = "GPL"; /* HID-BPF kfunc API definitions */ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t __sz) __ksym; struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 4096 * 64); } ringbuf SEC(".maps"); __u8 current_value = 0; SEC("struct_ops/hid_device_event") int BPF_PROG(filter_switch, struct hid_bpf_ctx *hid_ctx) { __u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 192 /* size */); __u8 *buf; if (!data) return 0; /* EPERM check */ if (current_value != data[152]) { buf = bpf_ringbuf_reserve(&ringbuf, 1, 0); if (!buf) return 0; *buf = data[152]; bpf_ringbuf_commit(buf, 0); current_value = data[152]; } return 0; } SEC(".struct_ops.link") struct hid_bpf_ops haptic_tablet = { .hid_device_event = (void *)filter_switch, };”…”�”}”hj-sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jõ h³hÇh´MthjÚ,h²hubhÞ)�”}”(hŒFTo attach ``haptic_tablet``, userspace needs to set ``hid_id`` first::”h]”(hŒ To attach ”…”�”}”(hj#-h²hh³Nh´Nubj")�”}”(hŒ``haptic_tablet``”h]”hŒ haptic_tablet”…”�”}”(hj+-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj#-ubhŒ, userspace needs to set ”…”�”}”(hj#-h²hh³Nh´Nubj")�”}”(hŒ ``hid_id``”h]”hŒhid_id”…”�”}”(hj=-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj#-ubhŒ first:”…”�”}”(hj#-h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M¥hjÚ,h²hubjö )�”}”(hXÝstatic int attach_filter(struct hid *hid_skel, int hid_id) { int err, link_fd; hid_skel->struct_ops.haptic_tablet->hid_id = hid_id; err = hid__load(skel); if (err) return err; link_fd = bpf_map__attach_struct_ops(hid_skel->maps.haptic_tablet); if (!link_fd) { fprintf(stderr, "can not attach HID-BPF program: %m\n"); return -1; } return link_fd; /* the fd of the created bpf_link */ }”h]”hXÝstatic int attach_filter(struct hid *hid_skel, int hid_id) { int err, link_fd; hid_skel->struct_ops.haptic_tablet->hid_id = hid_id; err = hid__load(skel); if (err) return err; link_fd = bpf_map__attach_struct_ops(hid_skel->maps.haptic_tablet); if (!link_fd) { fprintf(stderr, "can not attach HID-BPF program: %m\n"); return -1; } return link_fd; /* the fd of the created bpf_link */ }”…”�”}”hjU-sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jõ h³hÇh´M§hjÚ,h²hubhÞ)�”}”(hŒtOur userspace program can now listen to notifications on the ring buffer, and is awaken only when the value changes.”h]”hŒtOur userspace program can now listen to notifications on the ring buffer, and is awaken only when the value changes.”…”�”}”(hjc-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M¹hjÚ,h²hubhÞ)�”}”(hŒÐWhen the userspace program doesn't need to listen to events anymore, it can just close the returned bpf link from :c:func:`attach_filter`, which will tell the kernel to detach the program from the HID device.”h]”(hŒtWhen the userspace program doesn’t need to listen to events anymore, it can just close the returned bpf link from ”…”�”}”(hjq-h²hh³Nh´Nubh)�”}”(hŒ:c:func:`attach_filter`”h]”j")�”}”(hj{-h]”hŒattach_filter()”…”�”}”(hj}-h²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-func”eh"]”h$]”h&]”uh1j!hjy-ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jT jX j\ Œ attach_filter”uh1hh³hÇh´M¼hjq-ubhŒG, which will tell the kernel to detach the program from the HID device.”…”�”}”(hjq-h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M¼hjÚ,h²hubhÞ)�”}”(hŒ�Of course, in other use cases, the userspace program can also pin the fd to the BPF filesystem through a call to :c:func:`bpf_obj_pin`, as with any bpf_link.”h]”(hŒqOf course, in other use cases, the userspace program can also pin the fd to the BPF filesystem through a call to ”…”�”}”(hj¢-h²hh³Nh´Nubh)�”}”(hŒ:c:func:`bpf_obj_pin`”h]”j")�”}”(hj¬-h]”hŒ bpf_obj_pin()”…”�”}”(hj®-h²hh³Nh´Nubah}”(h]”h ]”(jB jÅ Œc-func”eh"]”h$]”h&]”uh1j!hjª-ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jN Œ refdomain”jÅ Œreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jT jX j\ Œ bpf_obj_pin”uh1hh³hÇh´MÀhj¢-ubhŒ, as with any bpf_link.”…”�”}”(hj¢-h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MÀhjÚ,h²hubeh}”(h]”jòah ]”h"]”Œfiltering events”ah$]”h&]”uh1hÈhj`,h²hh³hÇh´MiubhÉ)�”}”(hhh]”(hÎ)�”}”(hŒControlling the device”h]”hŒControlling the device”…”�”}”(hjÝ-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”jNjuh1hÍhjÚ-h²hh³hÇh´MÄubhÞ)�”}”(hŒ„To be able to change the haptic feedback from the tablet, the userspace program needs to emit a feature report on the device itself.”h]”hŒ„To be able to change the haptic feedback from the tablet, the userspace program needs to emit a feature report on the device itself.”…”�”}”(hjë-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MÆhjÚ-h²hubhÞ)�”}”(hŒgInstead of using hidraw for that, we can create a ``SEC("syscall")`` program that talks to the device::”h]”(hŒ2Instead of using hidraw for that, we can create a ”…”�”}”(hjù-h²hh³Nh´Nubj")�”}”(hŒ``SEC("syscall")``”h]”hŒSEC("syscall")”…”�”}”(hj.h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjù-ubhŒ" program that talks to the device:”…”�”}”(hjù-h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MÉhjÚ-h²hubjö )�”}”(hXW/* some more HID-BPF kfunc API definitions */ extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __ksym; extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym; extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8* data, size_t len, enum hid_report_type type, enum hid_class_request reqtype) __ksym; struct hid_send_haptics_args { /* data needs to come at offset 0 so we can do a memcpy into it */ __u8 data[10]; unsigned int hid; }; SEC("syscall") int send_haptic(struct hid_send_haptics_args *args) { struct hid_bpf_ctx *ctx; int ret = 0; ctx = hid_bpf_allocate_context(args->hid); if (!ctx) return 0; /* EPERM check */ ret = hid_bpf_hw_request(ctx, args->data, 10, HID_FEATURE_REPORT, HID_REQ_SET_REPORT); hid_bpf_release_context(ctx); return ret; }”h]”hXW/* some more HID-BPF kfunc API definitions */ extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __ksym; extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym; extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8* data, size_t len, enum hid_report_type type, enum hid_class_request reqtype) __ksym; struct hid_send_haptics_args { /* data needs to come at offset 0 so we can do a memcpy into it */ __u8 data[10]; unsigned int hid; }; SEC("syscall") int send_haptic(struct hid_send_haptics_args *args) { struct hid_bpf_ctx *ctx; int ret = 0; ctx = hid_bpf_allocate_context(args->hid); if (!ctx) return 0; /* EPERM check */ ret = hid_bpf_hw_request(ctx, args->data, 10, HID_FEATURE_REPORT, HID_REQ_SET_REPORT); hid_bpf_release_context(ctx); return ret; }”…”�”}”hj.sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jõ h³hÇh´MÌhjÚ-h²hubhÞ)�”}”(hŒ8And then userspace needs to call that program directly::”h]”hŒ7And then userspace needs to call that program directly:”…”�”}”(hj'.h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MñhjÚ-h²hubjö )�”}”(hXGstatic int set_haptic(struct hid *hid_skel, int hid_id, __u8 haptic_value) { int err, prog_fd; int ret = -1; struct hid_send_haptics_args args = { .hid = hid_id, }; DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattrs, .ctx_in = &args, .ctx_size_in = sizeof(args), ); args.data[0] = 0x02; /* report ID of the feature on our device */ args.data[1] = haptic_value; prog_fd = bpf_program__fd(hid_skel->progs.set_haptic); err = bpf_prog_test_run_opts(prog_fd, &tattrs); return err; }”h]”hXGstatic int set_haptic(struct hid *hid_skel, int hid_id, __u8 haptic_value) { int err, prog_fd; int ret = -1; struct hid_send_haptics_args args = { .hid = hid_id, }; DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattrs, .ctx_in = &args, .ctx_size_in = sizeof(args), ); args.data[0] = 0x02; /* report ID of the feature on our device */ args.data[1] = haptic_value; prog_fd = bpf_program__fd(hid_skel->progs.set_haptic); err = bpf_prog_test_run_opts(prog_fd, &tattrs); return err; }”…”�”}”hj5.sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1jõ h³hÇh´MóhjÚ-h²hubhÞ)�”}”(hŒ±Now our userspace program is aware of the haptic state and can control it. The program could make this state further available to other userspace programs (e.g. via a DBus API).”h]”hŒ±Now our userspace program is aware of the haptic state and can control it. The program could make this state further available to other userspace programs (e.g. via a DBus API).”…”�”}”(hjC.h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´MhjÚ-h²hubhÞ)�”}”(hXThe interesting bit here is that we did not created a new kernel API for this. Which means that if there is a bug in our implementation, we can change the interface with the kernel at-will, because the userspace application is responsible for its own usage.”h]”hXThe interesting bit here is that we did not created a new kernel API for this. Which means that if there is a bug in our implementation, we can change the interface with the kernel at-will, because the userspace application is responsible for its own usage.”…”�”}”(hjQ.h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÝh³hÇh´M hjÚ-h²hubeh}”(h]”jah ]”h"]”Œcontrolling the device”ah$]”h&]”uh1hÈhj`,h²hh³hÇh´MÄubeh}”(h]”jÓah ]”h"]”Œ9an (almost) complete example of a bpf enhanced hid device”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´M[ubeh}”(h]”Œhid-bpf”ah ]”h"]”Œhid-bpf”ah$]”h&]”uh1hÈhhh²hh³hÇh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hÍNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j˜.Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jr.jo.j:j5j%jj¾j/jjQj&jsjhj•jªj·jjÙj™jjhj9jjjûj[j['j}jÖj®jjÐjNjòjT'jjW+jBjœ(jajP+jƒj *j*jg*jd*jI+jF+j],j±jj.jÓj×-jòjc.juŒ nametypes”}”(jr.‰j:‰j%‰j¾‰j‰j&‰jh‰jª‰j‰j™‰jh‰jˆjû‰j['‰jÖ‰j‰jN‰jT'‰jW+‰jœ(‰jP+‰j *‰jg*‰jI+‰j],‰jj.‰j×-‰jc.‰uh}”(jo.hÊj5hïjj=j/j]jQjÁjsjj•j)j·jkjÙj­jj(j9jœjjj[jkj}jþj®j j@ jI jÐjÙjöjüjòjj.j3jjQjnjsj`jejÛjàjBjGjöjûj©#j®#jBj^'jajo'jƒjŸ(j*jj)jd*j *jF+jj*j±jZ+jÓj`,jòjÚ,jjÚ-j jj)j jKjBjmjdj�j†j±j¨jÓjÊjjøj3jjUjLjwjnj¨j�jÊjÁjìjãjjj<j3j[jRj}jtj«j¢jÍjÄjìjãjjuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”j¦.Ks…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.