'sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget:/translations/zh_CN/driver-api/surface_aggregator/internalmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget:/translations/zh_TW/driver-api/surface_aggregator/internalmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget:/translations/it_IT/driver-api/surface_aggregator/internalmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget:/translations/ja_JP/driver-api/surface_aggregator/internalmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget:/translations/ko_KR/driver-api/surface_aggregator/internalmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget:/translations/sp_SP/driver-api/surface_aggregator/internalmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h!SPDX-License-Identifier: GPL-2.0+h]h!SPDX-License-Identifier: GPL-2.0+}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhT/var/lib/git/docbuild/linux/Documentation/driver-api/surface_aggregator/internal.rsthKubhsubstitution_definition)}(h9.. |ssh_ptl| replace:: :c:type:`struct ssh_ptl `h]h)}(h":c:type:`struct ssh_ptl `h]hliteral)}(hhh]hstruct ssh_ptl}(hhhhhNhNubah}(h]h ](xrefcc-typeeh"]h$]h&]uh1hhhubah}(h]h ]h"]h$]h&]refdoc&driver-api/surface_aggregator/internal refdomainhˌreftypetype refexplicitrefwarn reftargetssh_ptluh1hhhhKhhubah}(h]h ]h"]ssh_ptlah$]h&]uh1hhhhKhhhhubh)}(h6.. |ssh_ptl_submit| replace:: :c:func:`ssh_ptl_submit`h]h)}(h:c:func:`ssh_ptl_submit`h]h)}(hhh]hssh_ptl_submit()}(hhhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhhubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_ptl_submituh1hhhhKhhubah}(h]h ]h"]ssh_ptl_submitah$]h&]uh1hhhhKhhhhubh)}(h6.. |ssh_ptl_cancel| replace:: :c:func:`ssh_ptl_cancel`h]h)}(h:c:func:`ssh_ptl_cancel`h]h)}(hjh]hssh_ptl_cancel()}(hjhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_ptl_canceluh1hhhhKhjubah}(h]h ]h"]ssh_ptl_cancelah$]h&]uh1hhhhKhhhhubh)}(h:.. |ssh_ptl_shutdown| replace:: :c:func:`ssh_ptl_shutdown`h]h)}(h:c:func:`ssh_ptl_shutdown`h]h)}(hj@h]hssh_ptl_shutdown()}(hjBhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhj>ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_ptl_shutdownuh1hhhhKhj:ubah}(h]h ]h"]ssh_ptl_shutdownah$]h&]uh1hhhhKhhhhubh)}(h<.. |ssh_ptl_rx_rcvbuf| replace:: :c:func:`ssh_ptl_rx_rcvbuf`h]h)}(h:c:func:`ssh_ptl_rx_rcvbuf`h]h)}(hjjh]hssh_ptl_rx_rcvbuf()}(hjlhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjhubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_ptl_rx_rcvbufuh1hhhhKhjdubah}(h]h ]h"]ssh_ptl_rx_rcvbufah$]h&]uh1hhhhKhhhhubh)}(h9.. |ssh_rtl| replace:: :c:type:`struct ssh_rtl `h]h)}(h":c:type:`struct ssh_rtl `h]h)}(hjh]hstruct ssh_rtl}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssh_rtluh1hhhhKhjubah}(h]h ]h"]ssh_rtlah$]h&]uh1hhhhKhhhhubh)}(h6.. |ssh_rtl_submit| replace:: :c:func:`ssh_rtl_submit`h]h)}(h:c:func:`ssh_rtl_submit`h]h)}(hjh]hssh_rtl_submit()}(hjhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_rtl_submituh1hhhhK hjubah}(h]h ]h"]ssh_rtl_submitah$]h&]uh1hhhhK hhhhubh)}(h6.. |ssh_rtl_cancel| replace:: :c:func:`ssh_rtl_cancel`h]h)}(h:c:func:`ssh_rtl_cancel`h]h)}(hjh]hssh_rtl_cancel()}(hjhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_rtl_canceluh1hhhhK hjubah}(h]h ]h"]ssh_rtl_cancelah$]h&]uh1hhhhK hhhhubh)}(h:.. |ssh_rtl_shutdown| replace:: :c:func:`ssh_rtl_shutdown`h]h)}(h:c:func:`ssh_rtl_shutdown`h]h)}(hjh]hssh_rtl_shutdown()}(hjhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_rtl_shutdownuh1hhhhK hj ubah}(h]h ]h"]ssh_rtl_shutdownah$]h&]uh1hhhhK hhhhubh)}(hB.. |ssh_packet| replace:: :c:type:`struct ssh_packet `h]h)}(h(:c:type:`struct ssh_packet `h]h)}(hj<h]hstruct ssh_packet}(hj>hhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhj:ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ ssh_packetuh1hhhhK hj6ubah}(h]h ]h"] ssh_packetah$]h&]uh1hhhhK hhhhubh)}(h6.. |ssh_packet_get| replace:: :c:func:`ssh_packet_get`h]h)}(h:c:func:`ssh_packet_get`h]h)}(hjfh]hssh_packet_get()}(hjhhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjdubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_packet_getuh1hhhhK hj`ubah}(h]h ]h"]ssh_packet_getah$]h&]uh1hhhhK hhhhubh)}(h6.. |ssh_packet_put| replace:: :c:func:`ssh_packet_put`h]h)}(h:c:func:`ssh_packet_put`h]h)}(hjh]hssh_packet_put()}(hjhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_packet_putuh1hhhhKhjubah}(h]h ]h"]ssh_packet_putah$]h&]uh1hhhhKhhhhubh)}(hN.. |ssh_packet_ops| replace:: :c:type:`struct ssh_packet_ops `h]h)}(h0:c:type:`struct ssh_packet_ops `h]h)}(hjh]hstruct ssh_packet_ops}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssh_packet_opsuh1hhhhKhjubah}(h]h ]h"]ssh_packet_opsah$]h&]uh1hhhhKhhhhubh)}(hj.. |ssh_packet_base_priority| replace:: :c:type:`enum ssh_packet_base_priority `h]h)}(hB:c:type:`enum ssh_packet_base_priority `h]h)}(hjh]henum ssh_packet_base_priority}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssh_packet_base_priorityuh1hhhhKhjubah}(h]h ]h"]ssh_packet_base_priorityah$]h&]uh1hhhhKhhhhubh)}(hR.. |ssh_packet_flags| replace:: :c:type:`enum ssh_packet_flags `h]h)}(h2:c:type:`enum ssh_packet_flags `h]h)}(hjh]henum ssh_packet_flags}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssh_packet_flagsuh1hhhhKhjubah}(h]h ]h"]ssh_packet_flagsah$]h&]uh1hhhhKhhhhubh)}(h@.. |SSH_PACKET_PRIORITY| replace:: :c:func:`SSH_PACKET_PRIORITY`h]h)}(h:c:func:`SSH_PACKET_PRIORITY`h]h)}(hj8h]hSSH_PACKET_PRIORITY()}(hj:hhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhj6ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌SSH_PACKET_PRIORITYuh1hhhhKhj2ubah}(h]h ]h"]SSH_PACKET_PRIORITYah$]h&]uh1hhhhKhhhhubh)}(h?.. |ssh_frame| replace:: :c:type:`struct ssh_frame `h]h)}(h&:c:type:`struct ssh_frame `h]h)}(hjbh]hstruct ssh_frame}(hjdhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhj`ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ ssh_frameuh1hhhhKhj\ubah}(h]h ]h"] ssh_frameah$]h&]uh1hhhhKhhhhubh)}(hE.. |ssh_command| replace:: :c:type:`struct ssh_command `h]h)}(h*:c:type:`struct ssh_command `h]h)}(hjh]hstruct ssh_command}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ ssh_commanduh1hhhhKhjubah}(h]h ]h"] ssh_commandah$]h&]uh1hhhhKhhhhubh)}(hE.. |ssh_request| replace:: :c:type:`struct ssh_request `h]h)}(h*:c:type:`struct ssh_request `h]h)}(hjh]hstruct ssh_request}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ ssh_requestuh1hhhhKhjubah}(h]h ]h"] ssh_requestah$]h&]uh1hhhhKhhhhubh)}(h8.. |ssh_request_get| replace:: :c:func:`ssh_request_get`h]h)}(h:c:func:`ssh_request_get`h]h)}(hjh]hssh_request_get()}(hjhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_request_getuh1hhhhKhjubah}(h]h ]h"]ssh_request_getah$]h&]uh1hhhhKhhhhubh)}(h8.. |ssh_request_put| replace:: :c:func:`ssh_request_put`h]h)}(h:c:func:`ssh_request_put`h]h)}(hj h]hssh_request_put()}(hj hhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_request_putuh1hhhhKhjubah}(h]h ]h"]ssh_request_putah$]h&]uh1hhhhKhhhhubh)}(hQ.. |ssh_request_ops| replace:: :c:type:`struct ssh_request_ops `h]h)}(h2:c:type:`struct ssh_request_ops `h]h)}(hj4h]hstruct ssh_request_ops}(hj6hhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhj2ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssh_request_opsuh1hhhhKhj.ubah}(h]h ]h"]ssh_request_opsah$]h&]uh1hhhhKhhhhubh)}(h:.. |ssh_request_init| replace:: :c:func:`ssh_request_init`h]h)}(h:c:func:`ssh_request_init`h]h)}(hj^h]hssh_request_init()}(hj`hhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhj\ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssh_request_inituh1hhhhKhjXubah}(h]h ]h"]ssh_request_initah$]h&]uh1hhhhKhhhhubh)}(hU.. |ssh_request_flags| replace:: :c:type:`enum ssh_request_flags `h]h)}(h4:c:type:`enum ssh_request_flags `h]h)}(hjh]henum ssh_request_flags}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssh_request_flagsuh1hhhhKhjubah}(h]h ]h"]ssh_request_flagsah$]h&]uh1hhhhKhhhhubh)}(hQ.. |ssam_controller| replace:: :c:type:`struct ssam_controller `h]h)}(h2:c:type:`struct ssam_controller `h]h)}(hjh]hstruct ssam_controller}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssam_controlleruh1hhhhKhjubah}(h]h ]h"]ssam_controllerah$]h&]uh1hhhhKhhhhubh)}(hE.. |ssam_device| replace:: :c:type:`struct ssam_device `h]h)}(h*:c:type:`struct ssam_device `h]h)}(hjh]hstruct ssam_device}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ ssam_deviceuh1hhhhKhjubah}(h]h ]h"] ssam_deviceah$]h&]uh1hhhhKhhhhubh)}(hZ.. |ssam_device_driver| replace:: :c:type:`struct ssam_device_driver `h]h)}(h8:c:type:`struct ssam_device_driver `h]h)}(hjh]hstruct ssam_device_driver}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssam_device_driveruh1hhhhKhjubah}(h]h ]h"]ssam_device_driverah$]h&]uh1hhhhKhhhhubh)}(h:.. |ssam_client_bind| replace:: :c:func:`ssam_client_bind`h]h)}(h:c:func:`ssam_client_bind`h]h)}(hj0h]hssam_client_bind()}(hj2hhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhj.ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssam_client_binduh1hhhhKhj*ubah}(h]h ]h"]ssam_client_bindah$]h&]uh1hhhhKhhhhubh)}(h:.. |ssam_client_link| replace:: :c:func:`ssam_client_link`h]h)}(h:c:func:`ssam_client_link`h]h)}(hjZh]hssam_client_link()}(hj\hhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjXubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssam_client_linkuh1hhhhKhjTubah}(h]h ]h"]ssam_client_linkah$]h&]uh1hhhhKhhhhubh)}(hW.. |ssam_request_sync| replace:: :c:type:`struct ssam_request_sync `h]h)}(h6:c:type:`struct ssam_request_sync `h]h)}(hjh]hstruct ssam_request_sync}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssam_request_syncuh1hhhhK hj~ubah}(h]h ]h"]ssam_request_syncah$]h&]uh1hhhhK hhhhubh)}(h].. |ssam_event_registry| replace:: :c:type:`struct ssam_event_registry `h]h)}(h::c:type:`struct ssam_event_registry `h]h)}(hjh]hstruct ssam_event_registry}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssam_event_registryuh1hhhhK!hjubah}(h]h ]h"]ssam_event_registryah$]h&]uh1hhhhK!hhhhubh)}(hK.. |ssam_event_id| replace:: :c:type:`struct ssam_event_id `h]h)}(h.:c:type:`struct ssam_event_id `h]h)}(hjh]hstruct ssam_event_id}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ ssam_event_iduh1hhhhK"hjubah}(h]h ]h"] ssam_event_idah$]h&]uh1hhhhK"hhhhubh)}(h9.. |ssam_nf| replace:: :c:type:`struct ssam_nf `h]h)}(h":c:type:`struct ssam_nf `h]h)}(hjh]hstruct ssam_nf}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssam_nfuh1hhhhK#hjubah}(h]h ]h"]ssam_nfah$]h&]uh1hhhhK#hhhhubh)}(hB.. |ssam_nf_refcount_inc| replace:: :c:func:`ssam_nf_refcount_inc`h]h)}(h:c:func:`ssam_nf_refcount_inc`h]h)}(hj,h]hssam_nf_refcount_inc()}(hj.hhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhj*ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssam_nf_refcount_incuh1hhhhK$hj&ubah}(h]h ]h"]ssam_nf_refcount_incah$]h&]uh1hhhhK$hhhhubh)}(hB.. |ssam_nf_refcount_dec| replace:: :c:func:`ssam_nf_refcount_dec`h]h)}(h:c:func:`ssam_nf_refcount_dec`h]h)}(hjVh]hssam_nf_refcount_dec()}(hjXhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjTubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssam_nf_refcount_decuh1hhhhK%hjPubah}(h]h ]h"]ssam_nf_refcount_decah$]h&]uh1hhhhK%hhhhubh)}(hF.. |ssam_notifier_register| replace:: :c:func:`ssam_notifier_register`h]h)}(h :c:func:`ssam_notifier_register`h]h)}(hjh]hssam_notifier_register()}(hjhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhj~ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssam_notifier_registeruh1hhhhK&hjzubah}(h]h ]h"]ssam_notifier_registerah$]h&]uh1hhhhK&hhhhubh)}(hJ.. |ssam_notifier_unregister| replace:: :c:func:`ssam_notifier_unregister`h]h)}(h":c:func:`ssam_notifier_unregister`h]h)}(hjh]hssam_notifier_unregister()}(hjhhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssam_notifier_unregisteruh1hhhhK'hjubah}(h]h ]h"]ssam_notifier_unregisterah$]h&]uh1hhhhK'hhhhubh)}(h?.. |ssam_cplt| replace:: :c:type:`struct ssam_cplt `h]h)}(h&:c:type:`struct ssam_cplt `h]h)}(hjh]hstruct ssam_cplt}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ ssam_cpltuh1hhhhK(hjubah}(h]h ]h"] ssam_cpltah$]h&]uh1hhhhK(hhhhubh)}(hT.. |ssam_event_queue| replace:: :c:type:`struct ssam_event_queue `h]h)}(h4:c:type:`struct ssam_event_queue `h]h)}(hjh]hstruct ssam_event_queue}(hjhhhNhNubah}(h]h ](hhˌc-typeeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypetype refexplicitrefwarnh݌ssam_event_queueuh1hhhhK)hjubah}(h]h ]h"]ssam_event_queueah$]h&]uh1hhhhK)hhhhubh)}(hK.. |ssam_request_sync_submit| replace:: :c:func:`ssam_request_sync_submit` h]h)}(h":c:func:`ssam_request_sync_submit`h]h)}(hj(h]hssam_request_sync_submit()}(hj*hhhNhNubah}(h]h ](hhˌc-funceh"]h$]h&]uh1hhj&ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypefunc refexplicitrefwarnh݌ssam_request_sync_submituh1hhhhK*hj"ubah}(h]h ]h"]ssam_request_sync_submitah$]h&]uh1hhhhK*hhhhubhsection)}(hhh](htitle)}(hCore Driver Internalsh]hCore Driver Internals}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjNhhhhhK.ubh paragraph)}(hArchitectural overview of the Surface System Aggregator Module (SSAM) core and Surface Serial Hub (SSH) driver. For the API documentation, refer to:h]hArchitectural overview of the Surface System Aggregator Module (SSAM) core and Surface Serial Hub (SSH) driver. For the API documentation, refer to:}(hjchhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhK0hjNhhubhcompound)}(hhh]htoctree)}(hhh]h}(h]h ]h"]h$]h&]hh׌entries]N*driver-api/surface_aggregator/internal-apia includefiles]jamaxdepthKcaptionNglobhidden includehiddennumberedK titlesonly rawentries]uh1jvhhhK3hjsubah}(h]h ]toctree-wrapperah"]h$]h&]uh1jqhjNhhhhhNubjM)}(hhh](jR)}(hOverviewh]hOverview}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhK:ubjb)}(hdThe SSAM core implementation is structured in layers, somewhat following the SSH protocol structure:h]hdThe SSAM core implementation is structured in layers, somewhat following the SSH protocol structure:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhK hhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhKhj- hhubjb)}(hX/In addition to guarding the collections, after initial packet submission certain packet fields may only be accessed under one of the locks. Specifically, the packet priority must only be accessed while holding the queue lock and the packet timestamp must only be accessed while holding the pending lock.h]hX/In addition to guarding the collections, after initial packet submission certain packet fields may only be accessed under one of the locks. Specifically, the packet priority must only be accessed while holding the queue lock and the packet timestamp must only be accessed while holding the pending lock.}(hjL hhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhKhj- hhubjb)}(hOther parts of the packet transport layer are guarded independently. State flags are managed by atomic bit operations and, if necessary, memory barriers. Modifications to the timeout reaper work item and expiration date are guarded by their own lock.h]hOther parts of the packet transport layer are guarded independently. State flags are managed by atomic bit operations and, if necessary, memory barriers. Modifications to the timeout reaper work item and expiration date are guarded by their own lock.}(hjZ hhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhj- hhubjb)}(hXThe reference of the packet to the packet transport layer (``ptl``) is somewhat special. It is either set when the upper layer request is submitted or, if there is none, when the packet is first submitted. After it is set, it will not change its value. Functions that may run concurrently with submission, i.e. cancellation, can not rely on the ``ptl`` reference to be set. Access to it in these functions is guarded by ``READ_ONCE()``, whereas setting ``ptl`` is equally guarded with ``WRITE_ONCE()`` for symmetry.h](h;The reference of the packet to the packet transport layer (}(hjh hhhNhNubh)}(h``ptl``h]hptl}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjh ubhX) is somewhat special. It is either set when the upper layer request is submitted or, if there is none, when the packet is first submitted. After it is set, it will not change its value. Functions that may run concurrently with submission, i.e. cancellation, can not rely on the }(hjh hhhNhNubh)}(h``ptl``h]hptl}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjh ubhD reference to be set. Access to it in these functions is guarded by }(hjh hhhNhNubh)}(h``READ_ONCE()``h]h READ_ONCE()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjh ubh, whereas setting }(hjh hhhNhNubh)}(h``ptl``h]hptl}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjh ubh is equally guarded with }(hjh hhhNhNubh)}(h``WRITE_ONCE()``h]h WRITE_ONCE()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjh ubh for symmetry.}(hjh hhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM hj- hhubjb)}(hX Some packet fields may be read outside of the respective locks guarding them, specifically priority and state for tracing. In those cases, proper access is ensured by employing ``WRITE_ONCE()`` and ``READ_ONCE()``. Such read-only access is only allowed when stale values are not critical.h](hSome packet fields may be read outside of the respective locks guarding them, specifically priority and state for tracing. In those cases, proper access is ensured by employing }(hj hhhNhNubh)}(h``WRITE_ONCE()``h]h WRITE_ONCE()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh and }(hj hhhNhNubh)}(h``READ_ONCE()``h]h READ_ONCE()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhK. Such read-only access is only allowed when stale values are not critical.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhj- hhubjb)}(hXWith respect to the interface for higher layers, packet submission (|ssh_ptl_submit|), packet cancellation (|ssh_ptl_cancel|), data receival (|ssh_ptl_rx_rcvbuf|), and layer shutdown (|ssh_ptl_shutdown|) may always be executed concurrently with respect to each other. Note that packet submission may not run concurrently with itself for the same packet. Equally, shutdown and data receival may also not run concurrently with themselves (but may run concurrently with each other).h](hDWith respect to the interface for higher layers, packet submission (}(hjhhhNhNubh)}(hhh]h)}(hhh]hssh_ptl_submit()}(hj hhhNhNubah}(h]h ](hhheh"]h$]h&]uh1hhNhNhj ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjhhubh), packet cancellation (}(hjhhhNhNubh)}(hjh]h)}(hjh]hssh_ptl_cancel()}(hj-hhhNhNubah}(h]h ](hhj"eh"]h$]h&]uh1hhNhNhj*ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej/ refexplicitrefwarn reftargetj2uh1hhhhKhjhhubh), data receival (}(hjhhhNhNubh)}(hjjh]h)}(hjjh]hssh_ptl_rx_rcvbuf()}(hjMhhhNhNubah}(h]h ](hhjveh"]h$]h&]uh1hhNhNhjJubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjhhubh), and layer shutdown (}(hjhhhNhNubh)}(hj@h]h)}(hj@h]hssh_ptl_shutdown()}(hjmhhhNhNubah}(h]h ](hhjLeh"]h$]h&]uh1hhNhNhjjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejY refexplicitrefwarn reftargetj\uh1hhhhKhjhhubhX) may always be executed concurrently with respect to each other. Note that packet submission may not run concurrently with itself for the same packet. Equally, shutdown and data receival may also not run concurrently with themselves (but may run concurrently with each other).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhj- hhubeh}(h]concurrency-and-lockingah ]h"]h$]concurrency and lockingah&]uh1jLhjhhhhhKj1 Kubeh}(h]packet-transport-layerah ]h"]packet transport layerah$]h&]uh1jLhjNhhhhhKbubjM)}(hhh](jR)}(hRequest Transport Layerh]hRequest Transport Layer}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhM!ubjb)}(hX"The request transport layer is represented via |ssh_rtl| and builds on top of the packet transport layer. It deals with requests, i.e. SSH packets sent by the host containing a |ssh_command| as frame payload. This layer separates responses to requests from events, which are also sent by the EC via a |ssh_command| payload. While responses are handled in this layer, events are relayed to the next upper layer, i.e. the controller layer, via the corresponding callback. The request transport layer is structured around the following key concepts:h](h/The request transport layer is represented via }(hjhhhNhNubh)}(hjh]h)}(hjh]hstruct ssh_rtl}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjhhubhy and builds on top of the packet transport layer. It deals with requests, i.e. SSH packets sent by the host containing a }(hjhhhNhNubh)}(hjh]h)}(hjh]hstruct ssh_command}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjhhubho as frame payload. This layer separates responses to requests from events, which are also sent by the EC via a }(hjhhhNhNubh)}(hjh]h)}(hjh]hstruct ssh_command}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjhhubh payload. While responses are handled in this layer, events are relayed to the next upper layer, i.e. the controller layer, via the corresponding callback. The request transport layer is structured around the following key concepts:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM#hjhhubjM)}(hhh](jR)}(hRequesth]hRequest}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhM-ubjb)}(hXxRequests are packets with a command-type payload, sent from host to EC to query data from or trigger an action on it (or both simultaneously). They are represented by |ssh_request|, wrapping the underlying |ssh_packet| storing its message data (i.e. SSH frame with command payload). Note that all top-level representations, e.g. |ssam_request_sync| are built upon this struct.h](hRequests are packets with a command-type payload, sent from host to EC to query data from or trigger an action on it (or both simultaneously). They are represented by }(hj0hhhNhNubh)}(hjh]h)}(hjh]hstruct ssh_request}(hj;hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhj8ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhj0hhubh, wrapping the underlying }(hj0hhhNhNubh)}(hj<h]h)}(hj<h]hstruct ssh_packet}(hj[hhhNhNubah}(h]h ](hhjHeh"]h$]h&]uh1hhNhNhjXubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejU refexplicitrefwarn reftargetjXuh1hhhhK hj0hhubho storing its message data (i.e. SSH frame with command payload). Note that all top-level representations, e.g. }(hj0hhhNhNubh)}(hjh]h)}(hjh]hstruct ssam_request_sync}(hj{hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjxubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK hj0hhubh are built upon this struct.}(hj0hhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM/hjhhubjb)}(hX1As |ssh_request| extends |ssh_packet|, its lifetime is also managed by the reference counter inside the packet struct (which can be accessed via |ssh_request_get| and |ssh_request_put|). Once the counter reaches zero, the ``release()`` callback of the |ssh_request_ops| reference of the request is called.h](hAs }(hjhhhNhNubh)}(hjh]h)}(hjh]hstruct ssh_request}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjhhubh extends }(hjhhhNhNubh)}(hj<h]h)}(hj<h]hstruct ssh_packet}(hjhhhNhNubah}(h]h ](hhjHeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejU refexplicitrefwarn reftargetjXuh1hhhhK hjhhubhl, its lifetime is also managed by the reference counter inside the packet struct (which can be accessed via }(hjhhhNhNubh)}(hjh]h)}(hjh]hssh_request_get()}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjhhubh and }(hjhhhNhNubh)}(hj h]h)}(hj h]hssh_request_put()}(hj hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej# refexplicitrefwarn reftargetj&uh1hhhhKhjhhubh&). Once the counter reaches zero, the }(hjhhhNhNubh)}(h ``release()``h]h release()}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh callback of the }(hjhhhNhNubh)}(hj4h]h)}(hj4h]hstruct ssh_request_ops}(hj;hhhNhNubah}(h]h ](hhj@eh"]h$]h&]uh1hhNhNhj8ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejM refexplicitrefwarn reftargetjPuh1hhhhKhjhhubh$ reference of the request is called.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM6hjhhubjb)}(hXDRequests can have an optional response that is equally sent via a SSH message with command-type payload (from EC to host). The party constructing the request must know if a response is expected and mark this in the request flags provided to |ssh_request_init|, so that the request transport layer can wait for this response.h](hRequests can have an optional response that is equally sent via a SSH message with command-type payload (from EC to host). The party constructing the request must know if a response is expected and mark this in the request flags provided to }(hj^hhhNhNubh)}(hj^h]h)}(hj^h]hssh_request_init()}(hjihhhNhNubah}(h]h ](hhjjeh"]h$]h&]uh1hhNhNhjfubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejw refexplicitrefwarn reftargetjzuh1hhhhKhj^hhubhA, so that the request transport layer can wait for this response.}(hj^hhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM<hjhhubjb)}(hX+Similar to |ssh_packet|, |ssh_request| also has a ``complete()`` callback provided via its request ops reference and is guaranteed to be completed before it is released once it has been submitted to the request transport layer via |ssh_rtl_submit|. For a request without a response, successful completion will occur once the underlying packet has been successfully transmitted by the packet transport layer (i.e. from within the packet completion callback). For a request with response, successful completion will occur once the response has been received and matched to the request via its request ID (which happens on the packet layer's data-received callback running on the receiver thread). If the request is completed with an error, the status value will be set to the corresponding (negative) errno value.h](h Similar to }(hjhhhNhNubh)}(hj<h]h)}(hj<h]hstruct ssh_packet}(hjhhhNhNubah}(h]h ](hhjHeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejU refexplicitrefwarn reftargetjXuh1hhhhK hjhhubh, }(hjhhhNhNubh)}(hjh]h)}(hjh]hstruct ssh_request}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjhhubh also has a }(hjhhhNhNubh)}(h``complete()``h]h complete()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh callback provided via its request ops reference and is guaranteed to be completed before it is released once it has been submitted to the request transport layer via }(hjhhhNhNubh)}(hjh]h)}(hjh]hssh_rtl_submit()}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK hjhhubhX6. For a request without a response, successful completion will occur once the underlying packet has been successfully transmitted by the packet transport layer (i.e. from within the packet completion callback). For a request with response, successful completion will occur once the response has been received and matched to the request via its request ID (which happens on the packet layer’s data-received callback running on the receiver thread). If the request is completed with an error, the status value will be set to the corresponding (negative) errno value.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMBhjhhubjb)}(hThe state of a request is again managed via its ``state`` flags (|ssh_request_flags|), which also encode the request type. In particular, the following bits are noteworthy:h](h0The state of a request is again managed via its }(hj hhhNhNubh)}(h ``state``h]hstate}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh flags (}(hj hhhNhNubh)}(hjh]h)}(hjh]henum ssh_request_flags}(hj)hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhj&ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhj hhubhX), which also encode the request type. In particular, the following bits are noteworthy:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMOhjhhubj )}(hhh](j )}(hXx``SSH_REQUEST_SF_LOCKED_BIT``: This bit is set when completion, either through error or success, is imminent. It indicates that no further references of the request should be taken and any existing references should be dropped as soon as possible. The process setting this bit is responsible for removing any references to this request from the request queue and pending set. h]jb)}(hXw``SSH_REQUEST_SF_LOCKED_BIT``: This bit is set when completion, either through error or success, is imminent. It indicates that no further references of the request should be taken and any existing references should be dropped as soon as possible. The process setting this bit is responsible for removing any references to this request from the request queue and pending set.h](h)}(h``SSH_REQUEST_SF_LOCKED_BIT``h]hSSH_REQUEST_SF_LOCKED_BIT}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjSubhXZ: This bit is set when completion, either through error or success, is imminent. It indicates that no further references of the request should be taken and any existing references should be dropped as soon as possible. The process setting this bit is responsible for removing any references to this request from the request queue and pending set.}(hjShhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMShjOubah}(h]h ]h"]h$]h&]uh1j hjLhhhhhNubj )}(h``SSH_REQUEST_SF_COMPLETED_BIT``: This bit is set by the process running the ``complete()`` callback and is used to ensure that this callback only runs once. h]jb)}(h``SSH_REQUEST_SF_COMPLETED_BIT``: This bit is set by the process running the ``complete()`` callback and is used to ensure that this callback only runs once.h](h)}(h ``SSH_REQUEST_SF_COMPLETED_BIT``h]hSSH_REQUEST_SF_COMPLETED_BIT}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubh-: This bit is set by the process running the }(hjyhhhNhNubh)}(h``complete()``h]h complete()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubhB callback and is used to ensure that this callback only runs once.}(hjyhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMZhjuubah}(h]h ]h"]h$]h&]uh1j hjLhhhhhNubj )}(h``SSH_REQUEST_SF_QUEUED_BIT``: This bit is set when the request is queued on the request queue and cleared when it is dequeued. h]jb)}(h``SSH_REQUEST_SF_QUEUED_BIT``: This bit is set when the request is queued on the request queue and cleared when it is dequeued.h](h)}(h``SSH_REQUEST_SF_QUEUED_BIT``h]hSSH_REQUEST_SF_QUEUED_BIT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhb: This bit is set when the request is queued on the request queue and cleared when it is dequeued.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM^hjubah}(h]h ]h"]h$]h&]uh1j hjLhhhhhNubj )}(h``SSH_REQUEST_SF_PENDING_BIT``: This bit is set when the request is added to the pending set and cleared when it is removed from it. h]jb)}(h``SSH_REQUEST_SF_PENDING_BIT``: This bit is set when the request is added to the pending set and cleared when it is removed from it.h](h)}(h``SSH_REQUEST_SF_PENDING_BIT``h]hSSH_REQUEST_SF_PENDING_BIT}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhf: This bit is set when the request is added to the pending set and cleared when it is removed from it.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMahjubah}(h]h ]h"]h$]h&]uh1j hjLhhhhhNubeh}(h]h ]h"]h$]h&]j} j~ uh1j hhhMShjhhubeh}(h]requestah ]h"]requestah$]h&]uh1jLhjhhhhhM-ubjM)}(hhh](jR)}(h Request Queueh]h Request Queue}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhMeubjb)}(hThe request queue is the first of the two fundamental collections in the request transport layer. In contrast to the packet queue of the packet transport layer, it is not a priority queue and the simple first come first serve principle applies.h]hThe request queue is the first of the two fundamental collections in the request transport layer. In contrast to the packet queue of the packet transport layer, it is not a priority queue and the simple first come first serve principle applies.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMghjhhubjb)}(hXAll requests to be transmitted by the request transport layer must be submitted to this queue via |ssh_rtl_submit|. Once submitted, requests may not be re-submitted, and will not be re-submitted automatically on timeout. Instead, the request is completed with a timeout error. If desired, the caller can create and submit a new request for another try, but it must not submit the same request again.h](hbAll requests to be transmitted by the request transport layer must be submitted to this queue via }(hj&hhhNhNubh)}(hjh]h)}(hjh]hssh_rtl_submit()}(hj1hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhj.ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK hj&hhubhX. Once submitted, requests may not be re-submitted, and will not be re-submitted automatically on timeout. Instead, the request is completed with a timeout error. If desired, the caller can create and submit a new request for another try, but it must not submit the same request again.}(hj&hhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMlhjhhubeh}(h] request-queueah ]h"] request queueah$]h&]uh1jLhjhhhhhMeubjM)}(hhh](jR)}(h Pending Seth]h Pending Set}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1jQhj\hhhhhMtubjb)}(hXThe pending set is the second of the two fundamental collections in the request transport layer. This collection stores references to all pending requests, i.e. requests awaiting a response from the EC (similar to what the pending set of the packet transport layer does for packets).h]hXThe pending set is the second of the two fundamental collections in the request transport layer. This collection stores references to all pending requests, i.e. requests awaiting a response from the EC (similar to what the pending set of the packet transport layer does for packets).}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMvhj\hhubeh}(h]id1ah ]h"]h$]j/ ah&]uh1jLhjhhhhhMtj1 KubjM)}(hhh](jR)}(hTransmitter Taskh]hTransmitter Task}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhM|ubjb)}(hXThe transmitter task is scheduled when a new request is available for transmission. It checks if the next request on the request queue can be transmitted and, if so, submits its underlying packet to the packet transport layer. This check ensures that only a limited number of requests can be pending, i.e. waiting for a response, at the same time. If the request requires a response, the request is added to the pending set before its packet is submitted.h]hXThe transmitter task is scheduled when a new request is available for transmission. It checks if the next request on the request queue can be transmitted and, if so, submits its underlying packet to the packet transport layer. This check ensures that only a limited number of requests can be pending, i.e. waiting for a response, at the same time. If the request requires a response, the request is added to the pending set before its packet is submitted.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhM~hjhhubeh}(h]transmitter-taskah ]h"]transmitter taskah$]h&]uh1jLhjhhhhhM|ubjM)}(hhh](jR)}(hPacket Completion Callbackh]hPacket Completion Callback}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhMubjb)}(hThe packet completion callback is executed once the underlying packet of a request has been completed. In case of an error completion, the corresponding request is completed with the error value provided in this callback.h]hThe packet completion callback is executed once the underlying packet of a request has been completed. In case of an error completion, the corresponding request is completed with the error value provided in this callback.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhjhhubjb)}(hOn successful packet completion, further processing depends on the request. If the request expects a response, it is marked as transmitted and the request timeout is started. If the request does not expect a response, it is completed with success.h]hOn successful packet completion, further processing depends on the request. If the request expects a response, it is marked as transmitted and the request timeout is started. If the request does not expect a response, it is completed with success.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhjhhubeh}(h]packet-completion-callbackah ]h"]packet completion callbackah$]h&]uh1jLhjhhhhhMubjM)}(hhh](jR)}(hData-Received Callbackh]hData-Received Callback}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhMubjb)}(hThe data received callback notifies the request transport layer of data being received by the underlying packet transport layer via a data-type frame. In general, this is expected to be a command-type payload.h]hThe data received callback notifies the request transport layer of data being received by the underlying packet transport layer via a data-type frame. In general, this is expected to be a command-type payload.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhjhhubjb)}(hXvIf the request ID of the command is one of the request IDs reserved for events (one to ``SSH_NUM_EVENTS``, inclusively), it is forwarded to the event callback registered in the request transport layer. If the request ID indicates a response to a request, the respective request is looked up in the pending set and, if found and marked as transmitted, completed with success.h](hWIf the request ID of the command is one of the request IDs reserved for events (one to }(hjhhhNhNubh)}(h``SSH_NUM_EVENTS``h]hSSH_NUM_EVENTS}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhX , inclusively), it is forwarded to the event callback registered in the request transport layer. If the request ID indicates a response to a request, the respective request is looked up in the pending set and, if found and marked as transmitted, completed with success.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhjhhubeh}(h]data-received-callbackah ]h"]data-received callbackah$]h&]uh1jLhjhhhhhMubjM)}(hhh](jR)}(hTimeout Reaperh]hTimeout Reaper}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jQhj%hhhhhMubjb)}(hThe request-response-timeout is a per-request timeout for requests expecting a response. It is used to ensure that a request does not wait indefinitely on a response from the EC and is started after the underlying packet has been successfully completed.h]hThe request-response-timeout is a per-request timeout for requests expecting a response. It is used to ensure that a request does not wait indefinitely on a response from the EC and is started after the underlying packet has been successfully completed.}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhj%hhubjb)}(hXThis timeout is, similar to the packet acknowledgment timeout on the packet transport layer, handled via a dedicated reaper task. This task is essentially a work-item (re-)scheduled to run when the next request is set to time out. The work item then scans the set of pending requests for any requests that have timed out and completes them with ``-ETIMEDOUT`` as status. Requests will not be re-submitted automatically. Instead, the issuer of the request must construct and submit a new request, if so desired.h](hXYThis timeout is, similar to the packet acknowledgment timeout on the packet transport layer, handled via a dedicated reaper task. This task is essentially a work-item (re-)scheduled to run when the next request is set to time out. The work item then scans the set of pending requests for any requests that have timed out and completes them with }(hjDhhhNhNubh)}(h``-ETIMEDOUT``h]h -ETIMEDOUT}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjDubh as status. Requests will not be re-submitted automatically. Instead, the issuer of the request must construct and submit a new request, if so desired.}(hjDhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhj%hhubjb)}(hNote that this timeout, in combination with packet transmission and acknowledgment timeouts, guarantees that the request layer will always make progress, even if only through timing out packets, and never fully block.h]hNote that this timeout, in combination with packet transmission and acknowledgment timeouts, guarantees that the request layer will always make progress, even if only through timing out packets, and never fully block.}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhj%hhubeh}(h]id2ah ]h"]h$]j+ ah&]uh1jLhjhhhhhMj1 KubjM)}(hhh](jR)}(hConcurrency and Lockingh]hConcurrency and Locking}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjyhhhhhMubjb)}(hXSimilar to the packet transport layer, there are two main locks in the request transport layer: One guarding access to the request queue and one guarding access to the pending set. These collections may only be accessed and modified under the respective lock.h]hXSimilar to the packet transport layer, there are two main locks in the request transport layer: One guarding access to the request queue and one guarding access to the pending set. These collections may only be accessed and modified under the respective lock.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhjyhhubjb)}(hXOther parts of the request transport layer are guarded independently. State flags are (again) managed by atomic bit operations and, if necessary, memory barriers. Modifications to the timeout reaper work item and expiration date are guarded by their own lock.h]hXOther parts of the request transport layer are guarded independently. State flags are (again) managed by atomic bit operations and, if necessary, memory barriers. Modifications to the timeout reaper work item and expiration date are guarded by their own lock.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhjyhhubjb)}(hXSome request fields may be read outside of the respective locks guarding them, specifically the state for tracing. In those cases, proper access is ensured by employing ``WRITE_ONCE()`` and ``READ_ONCE()``. Such read-only access is only allowed when stale values are not critical.h](hSome request fields may be read outside of the respective locks guarding them, specifically the state for tracing. In those cases, proper access is ensured by employing }(hjhhhNhNubh)}(h``WRITE_ONCE()``h]h WRITE_ONCE()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(hjhhhNhNubh)}(h``READ_ONCE()``h]h READ_ONCE()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhK. Such read-only access is only allowed when stale values are not critical.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhjyhhubjb)}(hXWith respect to the interface for higher layers, request submission (|ssh_rtl_submit|), request cancellation (|ssh_rtl_cancel|), and layer shutdown (|ssh_rtl_shutdown|) may always be executed concurrently with respect to each other. Note that request submission may not run concurrently with itself for the same request (and also may only be called once per request). Equally, shutdown may also not run concurrently with itself.h](hEWith respect to the interface for higher layers, request submission (}(hjhhhNhNubh)}(hjh]h)}(hjh]hssh_rtl_submit()}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK hjhhubh), request cancellation (}(hjhhhNhNubh)}(hjh]h)}(hjh]hssh_rtl_cancel()}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK hjhhubh), and layer shutdown (}(hjhhhNhNubh)}(hjh]h)}(hjh]hssh_rtl_shutdown()}(hj#hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhj ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej+ refexplicitrefwarn reftargetj.uh1hhhhK hjhhubhX) may always be executed concurrently with respect to each other. Note that request submission may not run concurrently with itself for the same request (and also may only be called once per request). Equally, shutdown may also not run concurrently with itself.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhjyhhubeh}(h]id3ah ]h"]h$]jah&]uh1jLhjhhhhhMj1 Kubeh}(h]request-transport-layerah ]h"]request transport layerah$]h&]uh1jLhjNhhhhhM!ubjM)}(hhh](jR)}(hController Layerh]hController Layer}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjUhhhhhMubjb)}(hXThe controller layer extends on the request transport layer to provide an easy-to-use interface for client drivers. It is represented by |ssam_controller| and the SSH driver. While the lower level transport layers take care of transmitting and handling packets and requests, the controller layer takes on more of a management role. Specifically, it handles device initialization, power management, and event handling, including event delivery and registration via the (event) completion system (|ssam_cplt|).h](hThe controller layer extends on the request transport layer to provide an easy-to-use interface for client drivers. It is represented by }(hjfhhhNhNubh)}(hjh]h)}(hjh]hstruct ssam_controller}(hjqhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjnubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhKhjfhhubhXU and the SSH driver. While the lower level transport layers take care of transmitting and handling packets and requests, the controller layer takes on more of a management role. Specifically, it handles device initialization, power management, and event handling, including event delivery and registration via the (event) completion system (}(hjfhhhNhNubh)}(hjh]h)}(hjh]hstruct ssam_cplt}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK(hjfhhubh).}(hjfhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhjUhhubjM)}(hhh](jR)}(hEvent Registrationh]hEvent Registration}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhMubjb)}(hX*In general, an event (or rather a class of events) has to be explicitly requested by the host before the EC will send it (HID input events seem to be the exception). This is done via an event-enable request (similarly, events should be disabled via an event-disable request once no longer desired).h]hX*In general, an event (or rather a class of events) has to be explicitly requested by the host before the EC will send it (HID input events seem to be the exception). This is done via an event-enable request (similarly, events should be disabled via an event-disable request once no longer desired).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhjhhubjb)}(hX_The specific request used to enable (or disable) an event is given via an event registry, i.e. the governing authority of this event (so to speak), represented by |ssam_event_registry|. As parameters to this request, the target category and, depending on the event registry, instance ID of the event to be enabled must be provided. This (optional) instance ID must be zero if the registry does not use it. Together, target category and instance ID form the event ID, represented by |ssam_event_id|. In short, both, event registry and event ID, are required to uniquely identify a respective class of events.h](hThe specific request used to enable (or disable) an event is given via an event registry, i.e. the governing authority of this event (so to speak), represented by }(hjhhhNhNubh)}(hjh]h)}(hjh]hstruct ssam_event_registry}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK!hjhhubhX*. As parameters to this request, the target category and, depending on the event registry, instance ID of the event to be enabled must be provided. This (optional) instance ID must be zero if the registry does not use it. Together, target category and instance ID form the event ID, represented by }(hjhhhNhNubh)}(hjh]h)}(hjh]hstruct ssam_event_id}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK"hjhhubhn. In short, both, event registry and event ID, are required to uniquely identify a respective class of events.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhjhhubjb)}(hX'Note that a further *request ID* parameter must be provided for the enable-event request. This parameter does not influence the class of events being enabled, but instead is set as the request ID (RQID) on each event of this class sent by the EC. It is used to identify events (as a limited number of request IDs is reserved for use in events only, specifically one to ``SSH_NUM_EVENTS`` inclusively) and also map events to their specific class. Currently, the controller always sets this parameter to the target category specified in |ssam_event_id|.h](hNote that a further }(hj!hhhNhNubj)}(h *request ID*h]h request ID}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj!ubhXQ parameter must be provided for the enable-event request. This parameter does not influence the class of events being enabled, but instead is set as the request ID (RQID) on each event of this class sent by the EC. It is used to identify events (as a limited number of request IDs is reserved for use in events only, specifically one to }(hj!hhhNhNubh)}(h``SSH_NUM_EVENTS``h]hSSH_NUM_EVENTS}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj!ubh inclusively) and also map events to their specific class. Currently, the controller always sets this parameter to the target category specified in }(hj!hhhNhNubh)}(hjh]h)}(hjh]hstruct ssam_event_id}(hjPhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjMubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK"hj!hhubh.}(hj!hhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhjhhubjb)}(hXAs multiple client drivers may rely on the same (or overlapping) classes of events and enable/disable calls are strictly binary (i.e. on/off), the controller has to manage access to these events. It does so via reference counting, storing the counter inside an RB-tree based mapping with event registry and ID as key (there is no known list of valid event registry and event ID combinations). See |ssam_nf|, |ssam_nf_refcount_inc|, and |ssam_nf_refcount_dec| for details.h](hXAs multiple client drivers may rely on the same (or overlapping) classes of events and enable/disable calls are strictly binary (i.e. on/off), the controller has to manage access to these events. It does so via reference counting, storing the counter inside an RB-tree based mapping with event registry and ID as key (there is no known list of valid event registry and event ID combinations). See }(hjshhhNhNubh)}(hjh]h)}(hjh]hstruct ssam_nf}(hj~hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhj{ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK#hjshhubh, }(hjshhhNhNubh)}(hj,h]h)}(hj,h]hssam_nf_refcount_inc()}(hjhhhNhNubah}(h]h ](hhj8eh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejE refexplicitrefwarn reftargetjHuh1hhhhK$hjshhubh, and }(hjshhhNhNubh)}(hjVh]h)}(hjVh]hssam_nf_refcount_dec()}(hjhhhNhNubah}(h]h ](hhjbeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejo refexplicitrefwarn reftargetjruh1hhhhK%hjshhubh for details.}(hjshhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhjhhubjb)}(hThis management is done together with notifier registration (described in the next section) via the top-level |ssam_notifier_register| and |ssam_notifier_unregister| functions.h](hnThis management is done together with notifier registration (described in the next section) via the top-level }(hjhhhNhNubh)}(hjh]h)}(hjh]hssam_notifier_register()}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK&hjhhubh and }(hjhhhNhNubh)}(hjh]h)}(hjh]hssam_notifier_unregister()}(hj hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhj ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK'hjhhubh functions.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhjhhubeh}(h]event-registrationah ]h"]event registrationah$]h&]uh1jLhjUhhhhhMubjM)}(hhh](jR)}(hEvent Deliveryh]hEvent Delivery}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jQhj7hhhhhMubjb)}(hX@To receive events, a client driver has to register an event notifier via |ssam_notifier_register|. This increments the reference counter for that specific class of events (as detailed in the previous section), enables the class on the EC (if it has not been enabled already), and installs the provided notifier callback.h](hITo receive events, a client driver has to register an event notifier via }(hjHhhhNhNubh)}(hjh]h)}(hjh]hssam_notifier_register()}(hjShhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjPubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK&hjHhhubh. This increments the reference counter for that specific class of events (as detailed in the previous section), enables the class on the EC (if it has not been enabled already), and installs the provided notifier callback.}(hjHhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhj7hhubjb)}(hXNotifier callbacks are stored in lists, with one (RCU) list per target category (provided via the event ID; NB: there is a fixed known number of target categories). There is no known association from the combination of event registry and event ID to the command data (target ID, target category, command ID, and instance ID) that can be provided by an event class, apart from target category and instance ID given via the event ID.h]hXNotifier callbacks are stored in lists, with one (RCU) list per target category (provided via the event ID; NB: there is a fixed known number of target categories). There is no known association from the combination of event registry and event ID to the command data (target ID, target category, command ID, and instance ID) that can be provided by an event class, apart from target category and instance ID given via the event ID.}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhM hj7hhubjb)}(hXNote that due to the way notifiers are (or rather have to be) stored, client drivers may receive events that they have not requested and need to account for them. Specifically, they will, by default, receive all events from the same target category. To simplify dealing with this, filtering of events by target ID (provided via the event registry) and instance ID (provided via the event ID) can be requested when registering a notifier. This filtering is applied when iterating over the notifiers at the time they are executed.h]hXNote that due to the way notifiers are (or rather have to be) stored, client drivers may receive events that they have not requested and need to account for them. Specifically, they will, by default, receive all events from the same target category. To simplify dealing with this, filtering of events by target ID (provided via the event registry) and instance ID (provided via the event ID) can be requested when registering a notifier. This filtering is applied when iterating over the notifiers at the time they are executed.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhMhj7hhubjb)}(hX All notifier callbacks are executed on a dedicated workqueue, the so-called completion workqueue. After an event has been received via the callback installed in the request layer (running on the receiver thread of the packet transport layer), it will be put on its respective event queue (|ssam_event_queue|). From this event queue the completion work item of that queue (running on the completion workqueue) will pick up the event and execute the notifier callback. This is done to avoid blocking on the receiver thread.h](hX!All notifier callbacks are executed on a dedicated workqueue, the so-called completion workqueue. After an event has been received via the callback installed in the request layer (running on the receiver thread of the packet transport layer), it will be put on its respective event queue (}(hjhhhNhNubh)}(hjh]h)}(hjh]hstruct ssam_event_queue}(hjhhhNhNubah}(h]h ](hhj eh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK)hjhhubh). From this event queue the completion work item of that queue (running on the completion workqueue) will pick up the event and execute the notifier callback. This is done to avoid blocking on the receiver thread.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhMhj7hhubjb)}(hX8There is one event queue per combination of target ID and target category. This is done to ensure that notifier callbacks are executed in sequence for events of the same target ID and target category. Callbacks can be executed in parallel for events with a different combination of target ID and target category.h]hX8There is one event queue per combination of target ID and target category. This is done to ensure that notifier callbacks are executed in sequence for events of the same target ID and target category. Callbacks can be executed in parallel for events with a different combination of target ID and target category.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhM#hj7hhubeh}(h]event-deliveryah ]h"]event deliveryah$]h&]uh1jLhjUhhhhhMubjM)}(hhh](jR)}(hConcurrency and Lockingh]hConcurrency and Locking}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jQhjhhhhhM*ubjb)}(hMost of the concurrency related safety guarantees of the controller are provided by the lower-level request transport layer. In addition to this, event (un-)registration is guarded by its own lock.h]hMost of the concurrency related safety guarantees of the controller are provided by the lower-level request transport layer. In addition to this, event (un-)registration is guarded by its own lock.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahhhM,hjhhubjb)}(hXCAccess to the controller state is guarded by the state lock. This lock is a read/write semaphore. The reader part can be used to ensure that the state does not change while functions depending on the state to stay the same (e.g. |ssam_notifier_register|, |ssam_notifier_unregister|, |ssam_request_sync_submit|, and derivatives) are executed and this guarantee is not already provided otherwise (e.g. through |ssam_client_bind| or |ssam_client_link|). The writer part guards any transitions that will change the state, i.e. initialization, destruction, suspension, and resumption.h](hAccess to the controller state is guarded by the state lock. This lock is a read/write semaphore. The reader part can be used to ensure that the state does not change while functions depending on the state to stay the same (e.g. }(hjhhhNhNubh)}(hjh]h)}(hjh]hssam_notifier_register()}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK&hjhhubh, }(hjhhhNhNubh)}(hjh]h)}(hjh]hssam_notifier_unregister()}(hj hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK'hjhhubh, }(hjhhhNhNubh)}(hj(h]h)}(hj(h]hssam_request_sync_submit()}(hj@hhhNhNubah}(h]h ](hhj4eh"]h$]h&]uh1hhNhNhj=ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejA refexplicitrefwarn reftargetjDuh1hhhhK*hjhhubhc, and derivatives) are executed and this guarantee is not already provided otherwise (e.g. through }(hjhhhNhNubh)}(hj0h]h)}(hj0h]hssam_client_bind()}(hj`hhhNhNubah}(h]h ](hhj<eh"]h$]h&]uh1hhNhNhj]ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejI refexplicitrefwarn reftargetjLuh1hhhhKhjhhubh or }(hjhhhNhNubh)}(hjZh]h)}(hjZh]hssam_client_link()}(hjhhhNhNubah}(h]h ](hhjfeh"]h$]h&]uh1hhNhNhj}ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejs refexplicitrefwarn reftargetjvuh1hhhhKhjhhubh). The writer part guards any transitions that will change the state, i.e. initialization, destruction, suspension, and resumption.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM0hjhhubjb)}(hX~The controller state may be accessed (read-only) outside the state lock for smoke-testing against invalid API usage (e.g. in |ssam_request_sync_submit|). Note that such checks are not supposed to (and will not) protect against all invalid usages, but rather aim to help catch them. In those cases, proper variable access is ensured by employing ``WRITE_ONCE()`` and ``READ_ONCE()``.h](h}The controller state may be accessed (read-only) outside the state lock for smoke-testing against invalid API usage (e.g. in }(hjhhhNhNubh)}(hj(h]h)}(hj(h]hssam_request_sync_submit()}(hjhhhNhNubah}(h]h ](hhj4eh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejA refexplicitrefwarn reftargetjDuh1hhhhK*hjhhubh). Note that such checks are not supposed to (and will not) protect against all invalid usages, but rather aim to help catch them. In those cases, proper variable access is ensured by employing }(hjhhhNhNubh)}(h``WRITE_ONCE()``h]h WRITE_ONCE()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh and }(hjhhhNhNubh)}(h``READ_ONCE()``h]h READ_ONCE()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM9hjhhubjb)}(hX4Assuming any preconditions on the state not changing have been satisfied, all non-initialization and non-shutdown functions may run concurrently with each other. This includes |ssam_notifier_register|, |ssam_notifier_unregister|, |ssam_request_sync_submit|, as well as all functions building on top of those.h](hAssuming any preconditions on the state not changing have been satisfied, all non-initialization and non-shutdown functions may run concurrently with each other. This includes }(hjhhhNhNubh)}(hjh]h)}(hjh]hssam_notifier_register()}(hjhhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK&hjhhubh, }(hjhhhNhNubh)}(hjh]h)}(hjh]hssam_notifier_unregister()}(hj hhhNhNubah}(h]h ](hhjeh"]h$]h&]uh1hhNhNhjubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypej refexplicitrefwarn reftargetjuh1hhhhK'hjhhubh, }(hjhhhNhNubh)}(hj(h]h)}(hj(h]hssam_request_sync_submit()}(hj@hhhNhNubah}(h]h ](hhj4eh"]h$]h&]uh1hhNhNhj=ubah}(h]h ]h"]h$]h&]refdoch׌ refdomainhˌreftypejA refexplicitrefwarn reftargetjDuh1hhhhK*hjhhubh4, as well as all functions building on top of those.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jahhhM?hjhhubeh}(h]id4ah ]h"]h$]concurrency and lockingah&]uh1jLhjUhhhhhM*j1 Kubeh}(h]controller-layerah ]h"]controller layerah$]h&]uh1jLhjNhhhhhMubeh}(h]core-driver-internalsah ]h"]core driver internalsah$]h&]uh1jLhhhhhhhK.ubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jQN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}(hhj hj7jjaj:jjdjjjjj jj3j j]j6jj`jjjjjjj/jjYj2jj\jjjjjjj+jjUj.jjXjjjjjjj'jjQj*j{jTjj~jjjjj#jjMj&jwjPjjzjjjjjjjIj"usubstitution_names}(ssh_ptlhssh_ptl_submitj ssh_ptl_cancelj7ssh_ptl_shutdownjassh_ptl_rx_rcvbufjssh_rtljssh_rtl_submitjssh_rtl_cancelj ssh_rtl_shutdownj3 ssh_packetj]ssh_packet_getjssh_packet_putjssh_packet_opsjssh_packet_base_priorityjssh_packet_flagsj/ssh_packet_priorityjY ssh_framej ssh_commandj ssh_requestjssh_request_getjssh_request_putj+ssh_request_opsjUssh_request_initjssh_request_flagsjssam_controllerj ssam_devicejssam_device_driverj'ssam_client_bindjQssam_client_linkj{ssam_request_syncjssam_event_registryj ssam_event_idjssam_nfj#ssam_nf_refcount_incjMssam_nf_refcount_decjwssam_notifier_registerjssam_notifier_unregisterj ssam_cpltjssam_event_queuejssam_request_sync_submitjIurefnames}refids}nameids}(jxjujjjjj j j j pending setNjd ja j j timeout reaperNconcurrency and lockingNjRjOjjjYjVjjjjj"jjpjmj4j1jju nametypes}(jxjjj j j jd j j j jRjjYjjj"jpj4juh}(jujNjjjjj jj j j+ j ja j2 j jg j' j jj- jOjjjjVjj}j\jjjjjjjtj%jHjyjmjUj1jjj7jeju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jKsRparse_messages](hsystem_message)}(hhh]jb)}(h.Duplicate implicit target name: "pending set".h]h2Duplicate implicit target name: “pending set”.}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1jahj-ubah}(h]h ]h"]h$]h&]j}alevelKtypeINFOsourcehlineMtuh1j+hj\hhhhhMtubj,)}(hhh]jb)}(h1Duplicate implicit target name: "timeout reaper".h]h5Duplicate implicit target name: “timeout reaper”.}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1jahjIubah}(h]h ]h"]h$]h&]jtalevelKtypejFsourcehlineMuh1j+hj%hhhhhMubj,)}(hhh]jb)}(h:Duplicate implicit target name: "concurrency and locking".h]h>Duplicate implicit target name: “concurrency and locking”.}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1jahjdubah}(h]h ]h"]h$]h&]jHalevelKtypejFsourcehlineMuh1j+hjyhhhhhMubj,)}(hhh]jb)}(h:Duplicate implicit target name: "concurrency and locking".h]h>Duplicate implicit target name: “concurrency and locking”.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jahjubah}(h]h ]h"]h$]h&]jealevelKtypejFsourcehlineM*uh1j+hjhhhhhM*ubetransform_messages] transformerN include_log] decorationNhhub.