Fsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget!/translations/zh_CN/PCI/msi-howtomodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/zh_TW/PCI/msi-howtomodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/it_IT/PCI/msi-howtomodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/ja_JP/PCI/msi-howtomodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/ko_KR/PCI/msi-howtomodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/sp_SP/PCI/msi-howtomodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh;/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto.rsthKubh)}(h4This data file has been placed in the public domain.h]h4This data file has been placed in the public domain.}hhsbah}(h]h ]h"]h$]h&]hhuh1hhhhhho/srv/docbuild/lib/venvs/build-kernel-docs/lib64/python3.9/site-packages/docutils/parsers/rst/include/isonum.txthKubh)}(hDerived from the Unicode character mappings available from . Processed by unicode2rstsubs.py, part of Docutils: .h]hDerived from the Unicode character mappings available from . Processed by unicode2rstsubs.py, part of Docutils: .}hhsbah}(h]h ]h"]h$]h&]hhuh1hhhhhhhhKubhsubstitution_definition)}(h*.. |amp| unicode:: U+00026 .. AMPERSANDh]h&}hhsbah}(h]h ]h"]ampah$]h&]uh1hhhhKhhhhubh)}(h+.. |apos| unicode:: U+00027 .. APOSTROPHEh]h'}hhsbah}(h]h ]h"]aposah$]h&]uh1hhhhKhhhhubh)}(h).. |ast| unicode:: U+0002A .. ASTERISKh]h*}hhsbah}(h]h ]h"]astah$]h&]uh1hhhhK hhhhubh)}(h+.. |brvbar| unicode:: U+000A6 .. BROKEN BARh]h¦}hjsbah}(h]h ]h"]brvbarah$]h&]uh1hhhhK hhhhubh)}(h0.. |bsol| unicode:: U+0005C .. REVERSE SOLIDUSh]h\}hjsbah}(h]h ]h"]bsolah$]h&]uh1hhhhK hhhhubh)}(h*.. |cent| unicode:: U+000A2 .. CENT SIGNh]h¢}hjsbah}(h]h ]h"]centah$]h&]uh1hhhhK hhhhubh)}(h&.. |colon| unicode:: U+0003A .. COLONh]h:}hj-sbah}(h]h ]h"]colonah$]h&]uh1hhhhK hhhhubh)}(h&.. |comma| unicode:: U+0002C .. COMMAh]h,}hj<sbah}(h]h ]h"]commaah$]h&]uh1hhhhKhhhhubh)}(h... |commat| unicode:: U+00040 .. COMMERCIAL ATh]h@}hjKsbah}(h]h ]h"]commatah$]h&]uh1hhhhKhhhhubh)}(h/.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGNh]h©}hjZsbah}(h]h ]h"]copyah$]h&]uh1hhhhKhhhhubh)}(h... |curren| unicode:: U+000A4 .. CURRENCY SIGNh]h¤}hjisbah}(h]h ]h"]currenah$]h&]uh1hhhhKhhhhubh)}(h0.. |darr| unicode:: U+02193 .. DOWNWARDS ARROWh]h↓}hjxsbah}(h]h ]h"]darrah$]h&]uh1hhhhKhhhhubh)}(h,.. |deg| unicode:: U+000B0 .. DEGREE SIGNh]h°}hjsbah}(h]h ]h"]degah$]h&]uh1hhhhKhhhhubh)}(h... |divide| unicode:: U+000F7 .. DIVISION SIGNh]h÷}hjsbah}(h]h ]h"]divideah$]h&]uh1hhhhKhhhhubh)}(h,.. |dollar| unicode:: U+00024 .. DOLLAR SIGNh]h$}hjsbah}(h]h ]h"]dollarah$]h&]uh1hhhhKhhhhubh)}(h,.. |equals| unicode:: U+0003D .. EQUALS SIGNh]h=}hjsbah}(h]h ]h"]equalsah$]h&]uh1hhhhKhhhhubh)}(h1.. |excl| unicode:: U+00021 .. EXCLAMATION MARKh]h!}hjsbah}(h]h ]h"]exclah$]h&]uh1hhhhKhhhhubh)}(h9.. |frac12| unicode:: U+000BD .. VULGAR FRACTION ONE HALFh]h½}hjsbah}(h]h ]h"]frac12ah$]h&]uh1hhhhKhhhhubh)}(h<.. |frac14| unicode:: U+000BC .. VULGAR FRACTION ONE QUARTERh]h¼}hjsbah}(h]h ]h"]frac14ah$]h&]uh1hhhhKhhhhubh)}(h;.. |frac18| unicode:: U+0215B .. VULGAR FRACTION ONE EIGHTHh]h⅛}hjsbah}(h]h ]h"]frac18ah$]h&]uh1hhhhKhhhhubh)}(h?.. |frac34| unicode:: U+000BE .. VULGAR FRACTION THREE QUARTERSh]h¾}hjsbah}(h]h ]h"]frac34ah$]h&]uh1hhhhKhhhhubh)}(h>.. |frac38| unicode:: U+0215C .. VULGAR FRACTION THREE EIGHTHSh]h⅜}hjsbah}(h]h ]h"]frac38ah$]h&]uh1hhhhKhhhhubh)}(h=.. |frac58| unicode:: U+0215D .. VULGAR FRACTION FIVE EIGHTHSh]h⅝}hjsbah}(h]h ]h"]frac58ah$]h&]uh1hhhhKhhhhubh)}(h>.. |frac78| unicode:: U+0215E .. VULGAR FRACTION SEVEN EIGHTHSh]h⅞}hj,sbah}(h]h ]h"]frac78ah$]h&]uh1hhhhKhhhhubh)}(h2.. |gt| unicode:: U+0003E .. GREATER-THAN SIGNh]h>}hj;sbah}(h]h ]h"]gtah$]h&]uh1hhhhKhhhhubh)}(h9.. |half| unicode:: U+000BD .. VULGAR FRACTION ONE HALFh]h½}hjJsbah}(h]h ]h"]halfah$]h&]uh1hhhhK hhhhubh)}(h/.. |horbar| unicode:: U+02015 .. HORIZONTAL BARh]h―}hjYsbah}(h]h ]h"]horbarah$]h&]uh1hhhhK!hhhhubh)}(h'.. |hyphen| unicode:: U+02010 .. HYPHENh]h‐}hjhsbah}(h]h ]h"]hyphenah$]h&]uh1hhhhK"hhhhubh)}(h:.. |iexcl| unicode:: U+000A1 .. INVERTED EXCLAMATION MARKh]h¡}hjwsbah}(h]h ]h"]iexclah$]h&]uh1hhhhK#hhhhubh)}(h7.. |iquest| unicode:: U+000BF .. INVERTED QUESTION MARKh]h¿}hjsbah}(h]h ]h"]iquestah$]h&]uh1hhhhK$hhhhubh)}(hJ.. |laquo| unicode:: U+000AB .. LEFT-POINTING DOUBLE ANGLE QUOTATION MARKh]h«}hjsbah}(h]h ]h"]laquoah$]h&]uh1hhhhK%hhhhubh)}(h0.. |larr| unicode:: U+02190 .. LEFTWARDS ARROWh]h←}hjsbah}(h]h ]h"]larrah$]h&]uh1hhhhK&hhhhubh)}(h3.. |lcub| unicode:: U+0007B .. LEFT CURLY BRACKETh]h{}hjsbah}(h]h ]h"]lcubah$]h&]uh1hhhhK'hhhhubh)}(h;.. |ldquo| unicode:: U+0201C .. LEFT DOUBLE QUOTATION MARKh]h“}hjsbah}(h]h ]h"]ldquoah$]h&]uh1hhhhK(hhhhubh)}(h).. |lowbar| unicode:: U+0005F .. LOW LINEh]h_}hjsbah}(h]h ]h"]lowbarah$]h&]uh1hhhhK)hhhhubh)}(h1.. |lpar| unicode:: U+00028 .. LEFT PARENTHESISh]h(}hjsbah}(h]h ]h"]lparah$]h&]uh1hhhhK*hhhhubh)}(h4.. |lsqb| unicode:: U+0005B .. LEFT SQUARE BRACKETh]h[}hjsbah}(h]h ]h"]lsqbah$]h&]uh1hhhhK+hhhhubh)}(h;.. |lsquo| unicode:: U+02018 .. LEFT SINGLE QUOTATION MARKh]h‘}hjsbah}(h]h ]h"]lsquoah$]h&]uh1hhhhK,hhhhubh)}(h/.. |lt| unicode:: U+0003C .. LESS-THAN SIGNh]h<}hj sbah}(h]h ]h"]ltah$]h&]uh1hhhhK-hhhhubh)}(h+.. |micro| unicode:: U+000B5 .. MICRO SIGNh]hµ}hjsbah}(h]h ]h"]microah$]h&]uh1hhhhK.hhhhubh)}(h+.. |middot| unicode:: U+000B7 .. MIDDLE DOTh]h·}hj+sbah}(h]h ]h"]middotah$]h&]uh1hhhhK/hhhhubh)}(h/.. |nbsp| unicode:: U+000A0 .. NO-BREAK SPACEh]h }hj:sbah}(h]h ]h"]nbspah$]h&]uh1hhhhK0hhhhubh)}(h).. |not| unicode:: U+000AC .. NOT SIGNh]h¬}hjIsbah}(h]h ]h"]notah$]h&]uh1hhhhK1hhhhubh)}(h,.. |num| unicode:: U+00023 .. NUMBER SIGNh]h#}hjXsbah}(h]h ]h"]numah$]h&]uh1hhhhK2hhhhubh)}(h).. |ohm| unicode:: U+02126 .. OHM SIGNh]hΩ}hjgsbah}(h]h ]h"]ohmah$]h&]uh1hhhhK3hhhhubh)}(h;.. |ordf| unicode:: U+000AA .. FEMININE ORDINAL INDICATORh]hª}hjvsbah}(h]h ]h"]ordfah$]h&]uh1hhhhK4hhhhubh)}(h<.. |ordm| unicode:: U+000BA .. MASCULINE ORDINAL INDICATORh]hº}hjsbah}(h]h ]h"]ordmah$]h&]uh1hhhhK5hhhhubh)}(h-.. |para| unicode:: U+000B6 .. PILCROW SIGNh]h¶}hjsbah}(h]h ]h"]paraah$]h&]uh1hhhhK6hhhhubh)}(h-.. |percnt| unicode:: U+00025 .. PERCENT SIGNh]h%}hjsbah}(h]h ]h"]percntah$]h&]uh1hhhhK7hhhhubh)}(h*.. |period| unicode:: U+0002E .. FULL STOPh]h.}hjsbah}(h]h ]h"]periodah$]h&]uh1hhhhK8hhhhubh)}(h*.. |plus| unicode:: U+0002B .. PLUS SIGNh]h+}hjsbah}(h]h ]h"]plusah$]h&]uh1hhhhK9hhhhubh)}(h0.. |plusmn| unicode:: U+000B1 .. PLUS-MINUS SIGNh]h±}hjsbah}(h]h ]h"]plusmnah$]h&]uh1hhhhK:hhhhubh)}(h+.. |pound| unicode:: U+000A3 .. POUND SIGNh]h£}hjsbah}(h]h ]h"]poundah$]h&]uh1hhhhK;hhhhubh)}(h... |quest| unicode:: U+0003F .. QUESTION MARKh]h?}hjsbah}(h]h ]h"]questah$]h&]uh1hhhhKhhhhubh)}(h1.. |rarr| unicode:: U+02192 .. RIGHTWARDS ARROWh]h→}hjsbah}(h]h ]h"]rarrah$]h&]uh1hhhhK?hhhhubh)}(h4.. |rcub| unicode:: U+0007D .. RIGHT CURLY BRACKETh]h}}hj*sbah}(h]h ]h"]rcubah$]h&]uh1hhhhK@hhhhubh)}(h<.. |rdquo| unicode:: U+0201D .. RIGHT DOUBLE QUOTATION MARKh]h”}hj9sbah}(h]h ]h"]rdquoah$]h&]uh1hhhhKAhhhhubh)}(h0.. |reg| unicode:: U+000AE .. REGISTERED SIGNh]h®}hjHsbah}(h]h ]h"]regah$]h&]uh1hhhhKBhhhhubh)}(h2.. |rpar| unicode:: U+00029 .. RIGHT PARENTHESISh]h)}hjWsbah}(h]h ]h"]rparah$]h&]uh1hhhhKChhhhubh)}(h5.. |rsqb| unicode:: U+0005D .. RIGHT SQUARE BRACKETh]h]}hjfsbah}(h]h ]h"]rsqbah$]h&]uh1hhhhKDhhhhubh)}(h<.. |rsquo| unicode:: U+02019 .. RIGHT SINGLE QUOTATION MARKh]h’}hjusbah}(h]h ]h"]rsquoah$]h&]uh1hhhhKEhhhhubh)}(h-.. |sect| unicode:: U+000A7 .. SECTION SIGNh]h§}hjsbah}(h]h ]h"]sectah$]h&]uh1hhhhKFhhhhubh)}(h*.. |semi| unicode:: U+0003B .. SEMICOLONh]h;}hjsbah}(h]h ]h"]semiah$]h&]uh1hhhhKGhhhhubh)}(h,.. |shy| unicode:: U+000AD .. SOFT HYPHENh]h­}hjsbah}(h]h ]h"]shyah$]h&]uh1hhhhKHhhhhubh)}(h(.. |sol| unicode:: U+0002F .. SOLIDUSh]h/}hjsbah}(h]h ]h"]solah$]h&]uh1hhhhKIhhhhubh)}(h,.. |sung| unicode:: U+0266A .. EIGHTH NOTEh]h♪}hjsbah}(h]h ]h"]sungah$]h&]uh1hhhhKJhhhhubh)}(h0.. |sup1| unicode:: U+000B9 .. SUPERSCRIPT ONEh]h¹}hjsbah}(h]h ]h"]sup1ah$]h&]uh1hhhhKKhhhhubh)}(h0.. |sup2| unicode:: U+000B2 .. SUPERSCRIPT TWOh]h²}hjsbah}(h]h ]h"]sup2ah$]h&]uh1hhhhKLhhhhubh)}(h2.. |sup3| unicode:: U+000B3 .. SUPERSCRIPT THREEh]h³}hjsbah}(h]h ]h"]sup3ah$]h&]uh1hhhhKMhhhhubh)}(h4.. |times| unicode:: U+000D7 .. MULTIPLICATION SIGNh]h×}hjsbah}(h]h ]h"]timesah$]h&]uh1hhhhKNhhhhubh)}(h0.. |trade| unicode:: U+02122 .. TRADE MARK SIGNh]h™}hj sbah}(h]h ]h"]tradeah$]h&]uh1hhhhKOhhhhubh)}(h... |uarr| unicode:: U+02191 .. UPWARDS ARROWh]h↑}hjsbah}(h]h ]h"]uarrah$]h&]uh1hhhhKPhhhhubh)}(h... |verbar| unicode:: U+0007C .. VERTICAL LINEh]h|}hj)sbah}(h]h ]h"]verbarah$]h&]uh1hhhhKQhhhhubh)}(h*.. |yen| unicode:: U+000A5 .. YEN SIGN h]h¥}hj8sbah}(h]h ]h"]yenah$]h&]uh1hhhhKRhhhhubhsection)}(hhh](htitle)}(hThe MSI Driver Guide HOWTOh]hThe MSI Driver Guide HOWTO}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjIhhhhhKubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hAuthorsh]hAuthors}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1jfhjchhhKubh field_body)}(h1Tom L Nguyen; Martine Silbermann; Matthew Wilcox h]h paragraph)}(h0Tom L Nguyen; Martine Silbermann; Matthew Wilcoxh]h0Tom L Nguyen; Martine Silbermann; Matthew Wilcox}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjxubah}(h]h ]h"]h$]h&]uh1jvhjcubeh}(h]h ]h"]h$]h&]uh1jahhhKhj^hhubjb)}(hhh](jg)}(h Copyrighth]h Copyright}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jfhjhhhKubjw)}(h2003, 2008 Intel Corporation h]j})}(h2003, 2008 Intel Corporationh]h2003, 2008 Intel Corporation}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhK hjubah}(h]h ]h"]h$]h&]uh1jvhjubeh}(h]h ]h"]h$]h&]uh1jahhhK hj^hhubeh}(h]h ]h"]h$]h&]uh1j\hjIhhhhhKubjH)}(hhh](jM)}(hAbout this guideh]hAbout this guide}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjhhhhhK ubj})}(hThis guide describes the basics of Message Signaled Interrupts (MSIs), the advantages of using MSI over traditional interrupt mechanisms, how to change your driver to use MSI or MSI-X and some basic diagnostics to try if a device doesn't support MSIs.h]hThis guide describes the basics of Message Signaled Interrupts (MSIs), the advantages of using MSI over traditional interrupt mechanisms, how to change your driver to use MSI or MSI-X and some basic diagnostics to try if a device doesn’t support MSIs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubeh}(h]about-this-guideah ]h"]about this guideah$]h&]uh1jGhjIhhhhhK ubjH)}(hhh](jM)}(hWhat are MSIs?h]hWhat are MSIs?}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjhhhhhKubj})}(hA Message Signaled Interrupt is a write from the device to a special address which causes an interrupt to be received by the CPU.h]hA Message Signaled Interrupt is a write from the device to a special address which causes an interrupt to be received by the CPU.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubj})}(hX%The MSI capability was first specified in PCI 2.2 and was later enhanced in PCI 3.0 to allow each interrupt to be masked individually. The MSI-X capability was also introduced with PCI 3.0. It supports more interrupts per device than MSI and allows interrupts to be independently configured.h]hX%The MSI capability was first specified in PCI 2.2 and was later enhanced in PCI 3.0 to allow each interrupt to be masked individually. The MSI-X capability was also introduced with PCI 3.0. It supports more interrupts per device than MSI and allows interrupts to be independently configured.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubj})}(hNDevices may support both MSI and MSI-X, but only one can be enabled at a time.h]hNDevices may support both MSI and MSI-X, but only one can be enabled at a time.}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhK hjhhubeh}(h] what-are-msisah ]h"]what are msis?ah$]h&]uh1jGhjIhhhhhKubjH)}(hhh](jM)}(h Why use MSIs?h]h Why use MSIs?}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jLhj7hhhhhK%ubj})}(hcThere are three reasons why using MSIs can give an advantage over traditional pin-based interrupts.h]hcThere are three reasons why using MSIs can give an advantage over traditional pin-based interrupts.}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhK'hj7hhubj})}(hXPin-based PCI interrupts are often shared amongst several devices. To support this, the kernel must call each interrupt handler associated with an interrupt, which leads to reduced performance for the system as a whole. MSIs are never shared, so this problem cannot arise.h]hXPin-based PCI interrupts are often shared amongst several devices. To support this, the kernel must call each interrupt handler associated with an interrupt, which leads to reduced performance for the system as a whole. MSIs are never shared, so this problem cannot arise.}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhK*hj7hhubj})}(hXWhen a device writes data to memory, then raises a pin-based interrupt, it is possible that the interrupt may arrive before all the data has arrived in memory (this becomes more likely with devices behind PCI-PCI bridges). In order to ensure that all the data has arrived in memory, the interrupt handler must read a register on the device which raised the interrupt. PCI transaction ordering rules require that all the data arrive in memory before the value may be returned from the register. Using MSIs avoids this problem as the interrupt-generating write cannot pass the data writes, so by the time the interrupt is raised, the driver knows that all the data has arrived in memory.h]hXWhen a device writes data to memory, then raises a pin-based interrupt, it is possible that the interrupt may arrive before all the data has arrived in memory (this becomes more likely with devices behind PCI-PCI bridges). In order to ensure that all the data has arrived in memory, the interrupt handler must read a register on the device which raised the interrupt. PCI transaction ordering rules require that all the data arrive in memory before the value may be returned from the register. Using MSIs avoids this problem as the interrupt-generating write cannot pass the data writes, so by the time the interrupt is raised, the driver knows that all the data has arrived in memory.}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhK/hj7hhubj})}(hXjPCI devices can only support a single pin-based interrupt per function. Often drivers have to query the device to find out what event has occurred, slowing down interrupt handling for the common case. With MSIs, a device can support more interrupts, allowing each interrupt to be specialised to a different purpose. One possible design gives infrequent conditions (such as errors) their own interrupt which allows the driver to handle the normal interrupt handling path more efficiently. Other possible designs include giving one interrupt to each packet queue in a network card or each port in a storage controller.h]hXjPCI devices can only support a single pin-based interrupt per function. Often drivers have to query the device to find out what event has occurred, slowing down interrupt handling for the common case. With MSIs, a device can support more interrupts, allowing each interrupt to be specialised to a different purpose. One possible design gives infrequent conditions (such as errors) their own interrupt which allows the driver to handle the normal interrupt handling path more efficiently. Other possible designs include giving one interrupt to each packet queue in a network card or each port in a storage controller.}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhK:hj7hhubeh}(h] why-use-msisah ]h"] why use msis?ah$]h&]uh1jGhjIhhhhhK%ubjH)}(hhh](jM)}(hHow to use MSIsh]hHow to use MSIs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjhhhhhKFubj})}(hXPCI devices are initialised to use pin-based interrupts. The device driver has to set up the device to use MSI or MSI-X. Not all machines support MSIs correctly, and for those machines, the APIs described below will simply fail and the device will continue to use pin-based interrupts.h]hXPCI devices are initialised to use pin-based interrupts. The device driver has to set up the device to use MSI or MSI-X. Not all machines support MSIs correctly, and for those machines, the APIs described below will simply fail and the device will continue to use pin-based interrupts.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKHhjhhubjH)}(hhh](jM)}(hInclude kernel support for MSIsh]hInclude kernel support for MSIs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjhhhhhKNubj})}(hX0To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI option enabled. This option is only available on some architectures, and it may depend on some other options also being set. For example, on x86, you must also enable X86_UP_APIC or SMP in order to see the CONFIG_PCI_MSI option.h]hX0To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI option enabled. This option is only available on some architectures, and it may depend on some other options also being set. For example, on x86, you must also enable X86_UP_APIC or SMP in order to see the CONFIG_PCI_MSI option.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKPhjhhubeh}(h]include-kernel-support-for-msisah ]h"]include kernel support for msisah$]h&]uh1jGhjhhhhhKNubjH)}(hhh](jM)}(h Using MSIh]h Using MSI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjhhhhhKWubj})}(hMost of the hard work is done for the driver in the PCI layer. The driver simply has to request that the PCI layer set up the MSI capability for this device.h]hMost of the hard work is done for the driver in the PCI layer. The driver simply has to request that the PCI layer set up the MSI capability for this device.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKYhjhhubj})}(hQTo automatically use MSI or MSI-X interrupt vectors, use the following function::h]hPTo automatically use MSI or MSI-X interrupt vectors, use the following function:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhK]hjhhubh literal_block)}(hint pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags);h]hint pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhK`hjhhubj})}(hXUwhich allocates up to max_vecs interrupt vectors for a PCI device. It returns the number of vectors allocated or a negative error. If the device has a requirements for a minimum number of vectors the driver can pass a min_vecs argument set to this limit, and the PCI core will return -ENOSPC if it can't meet the minimum number of vectors.h]hXWwhich allocates up to max_vecs interrupt vectors for a PCI device. It returns the number of vectors allocated or a negative error. If the device has a requirements for a minimum number of vectors the driver can pass a min_vecs argument set to this limit, and the PCI core will return -ENOSPC if it can’t meet the minimum number of vectors.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKchjhhubj})}(hXnThe flags argument is used to specify which type of interrupt can be used by the device and the driver (PCI_IRQ_INTX, PCI_IRQ_MSI, PCI_IRQ_MSIX). A convenient short-hand (PCI_IRQ_ALL_TYPES) is also available to ask for any possible kind of interrupt. If the PCI_IRQ_AFFINITY flag is set, pci_alloc_irq_vectors() will spread the interrupts around the available CPUs.h]hXnThe flags argument is used to specify which type of interrupt can be used by the device and the driver (PCI_IRQ_INTX, PCI_IRQ_MSI, PCI_IRQ_MSIX). A convenient short-hand (PCI_IRQ_ALL_TYPES) is also available to ask for any possible kind of interrupt. If the PCI_IRQ_AFFINITY flag is set, pci_alloc_irq_vectors() will spread the interrupts around the available CPUs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKihjhhubj})}(hqTo get the Linux IRQ numbers passed to request_irq() and free_irq() and the vectors, use the following function::h]hpTo get the Linux IRQ numbers passed to request_irq() and free_irq() and the vectors, use the following function:}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKohjhhubj)}(h9int pci_irq_vector(struct pci_dev *dev, unsigned int nr);h]h9int pci_irq_vector(struct pci_dev *dev, unsigned int nr);}hj5sbah}(h]h ]h"]h$]h&]hhuh1jhhhKrhjhhubj})}(haAny allocated resources should be freed before removing the device using the following function::h]h`Any allocated resources should be freed before removing the device using the following function:}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKthjhhubj)}(h/void pci_free_irq_vectors(struct pci_dev *dev);h]h/void pci_free_irq_vectors(struct pci_dev *dev);}hjQsbah}(h]h ]h"]h$]h&]hhuh1jhhhKwhjhhubj})}(hXNIf a device supports both MSI-X and MSI capabilities, this API will use the MSI-X facilities in preference to the MSI facilities. MSI-X supports any number of interrupts between 1 and 2048. In contrast, MSI is restricted to a maximum of 32 interrupts (and must be a power of two). In addition, the MSI interrupt vectors must be allocated consecutively, so the system might not be able to allocate as many vectors for MSI as it could for MSI-X. On some platforms, MSI interrupts must all be targeted at the same set of CPUs whereas MSI-X interrupts can all be targeted at different CPUs.h]hXNIf a device supports both MSI-X and MSI capabilities, this API will use the MSI-X facilities in preference to the MSI facilities. MSI-X supports any number of interrupts between 1 and 2048. In contrast, MSI is restricted to a maximum of 32 interrupts (and must be a power of two). In addition, the MSI interrupt vectors must be allocated consecutively, so the system might not be able to allocate as many vectors for MSI as it could for MSI-X. On some platforms, MSI interrupts must all be targeted at the same set of CPUs whereas MSI-X interrupts can all be targeted at different CPUs.}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKyhjhhubj})}(hZIf a device supports neither MSI-X or MSI it will fall back to a single legacy IRQ vector.h]hZIf a device supports neither MSI-X or MSI it will fall back to a single legacy IRQ vector.}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubj})}(hXEThe typical usage of MSI or MSI-X interrupts is to allocate as many vectors as possible, likely up to the limit supported by the device. If nvec is larger than the number supported by the device it will automatically be capped to the supported limit, so there is no need to query the number of vectors supported beforehand::h]hXDThe typical usage of MSI or MSI-X interrupts is to allocate as many vectors as possible, likely up to the limit supported by the device. If nvec is larger than the number supported by the device it will automatically be capped to the supported limit, so there is no need to query the number of vectors supported beforehand:}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubj)}(hbnvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES) if (nvec < 0) goto out_err;h]hbnvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_ALL_TYPES) if (nvec < 0) goto out_err;}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubj})}(hIf a driver is unable or unwilling to deal with a variable number of MSI interrupts it can request a particular number of interrupts by passing that number to pci_alloc_irq_vectors() function as both 'min_vecs' and 'max_vecs' parameters::h]hIf a driver is unable or unwilling to deal with a variable number of MSI interrupts it can request a particular number of interrupts by passing that number to pci_alloc_irq_vectors() function as both ‘min_vecs’ and ‘max_vecs’ parameters:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubj)}(hdret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES); if (ret < 0) goto out_err;h]hdret = pci_alloc_irq_vectors(pdev, nvec, nvec, PCI_IRQ_ALL_TYPES); if (ret < 0) goto out_err;}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubj})}(hThe most notorious example of the request type described above is enabling the single MSI mode for a device. It could be done by passing two 1s as 'min_vecs' and 'max_vecs'::h]hThe most notorious example of the request type described above is enabling the single MSI mode for a device. It could be done by passing two 1s as ‘min_vecs’ and ‘max_vecs’:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubj)}(h^ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); if (ret < 0) goto out_err;h]h^ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); if (ret < 0) goto out_err;}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubj})}(hSome devices might not support using legacy line interrupts, in which case the driver can specify that only MSI or MSI-X is acceptable::h]hSome devices might not support using legacy line interrupts, in which case the driver can specify that only MSI or MSI-X is acceptable:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubj)}(hlnvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX); if (nvec < 0) goto out_err;h]hlnvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_MSI | PCI_IRQ_MSIX); if (nvec < 0) goto out_err;}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubeh}(h] using-msiah ]h"] using msiah$]h&]uh1jGhjhhhhhKWubjH)}(hhh](jM)}(h Legacy APIsh]h Legacy APIs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjhhhhhKubj})}(heThe following old APIs to enable and disable MSI or MSI-X interrupts should not be used in new code::h]hdThe following old APIs to enable and disable MSI or MSI-X interrupts should not be used in new code:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubj)}(hpci_enable_msi() /* deprecated */ pci_disable_msi() /* deprecated */ pci_enable_msix_range() /* deprecated */ pci_enable_msix_exact() /* deprecated */ pci_disable_msix() /* deprecated */h]hpci_enable_msi() /* deprecated */ pci_disable_msi() /* deprecated */ pci_enable_msix_range() /* deprecated */ pci_enable_msix_exact() /* deprecated */ pci_disable_msix() /* deprecated */}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubj})}(hXAdditionally there are APIs to provide the number of supported MSI or MSI-X vectors: pci_msi_vec_count() and pci_msix_vec_count(). In general these should be avoided in favor of letting pci_alloc_irq_vectors() cap the number of vectors. If you have a legitimate special use case for the count of vectors we might have to revisit that decision and add a pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently.h]hXAdditionally there are APIs to provide the number of supported MSI or MSI-X vectors: pci_msi_vec_count() and pci_msix_vec_count(). In general these should be avoided in favor of letting pci_alloc_irq_vectors() cap the number of vectors. If you have a legitimate special use case for the count of vectors we might have to revisit that decision and add a pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubeh}(h] legacy-apisah ]h"] legacy apisah$]h&]uh1jGhjhhhhhKubjH)}(hhh](jM)}(hConsiderations when using MSIsh]hConsiderations when using MSIs}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1jLhj6hhhhhKubjH)}(hhh](jM)}(h Spinlocksh]h Spinlocks}(hjJhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjGhhhhhKubj})}(hXqMost device drivers have a per-device spinlock which is taken in the interrupt handler. With pin-based interrupts or a single MSI, it is not necessary to disable interrupts (Linux guarantees the same interrupt will not be re-entered). If a device uses multiple interrupts, the driver must disable interrupts while the lock is held. If the device sends a different interrupt, the driver will deadlock trying to recursively acquire the spinlock. Such deadlocks can be avoided by using spin_lock_irqsave() or spin_lock_irq() which disable local interrupts and acquire the lock (see Documentation/kernel-hacking/locking.rst).h]hXqMost device drivers have a per-device spinlock which is taken in the interrupt handler. With pin-based interrupts or a single MSI, it is not necessary to disable interrupts (Linux guarantees the same interrupt will not be re-entered). If a device uses multiple interrupts, the driver must disable interrupts while the lock is held. If the device sends a different interrupt, the driver will deadlock trying to recursively acquire the spinlock. Such deadlocks can be avoided by using spin_lock_irqsave() or spin_lock_irq() which disable local interrupts and acquire the lock (see Documentation/kernel-hacking/locking.rst).}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjGhhubeh}(h] spinlocksah ]h"] spinlocksah$]h&]uh1jGhj6hhhhhKubeh}(h]considerations-when-using-msisah ]h"]considerations when using msisah$]h&]uh1jGhjhhhhhKubjH)}(hhh](jM)}(h4How to tell whether MSI/MSI-X is enabled on a deviceh]h4How to tell whether MSI/MSI-X is enabled on a device}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjvhhhhhKubj})}(hUsing 'lspci -v' (as root) may show some devices with "MSI", "Message Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities has an 'Enable' flag which is followed with either "+" (enabled) or "-" (disabled).h]hXUsing ‘lspci -v’ (as root) may show some devices with “MSI”, “Message Signalled Interrupts” or “MSI-X” capabilities. Each of these capabilities has an ‘Enable’ flag which is followed with either “+” (enabled) or “-” (disabled).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjvhhubeh}(h]4how-to-tell-whether-msi-msi-x-is-enabled-on-a-deviceah ]h"]4how to tell whether msi/msi-x is enabled on a deviceah$]h&]uh1jGhjhhhhhKubeh}(h]how-to-use-msisah ]h"]how to use msisah$]h&]uh1jGhjIhhhhhKFubjH)}(hhh](jM)}(h MSI quirksh]h MSI quirks}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjhhhhhKubj})}(hqSeveral PCI chipsets or devices are known not to support MSIs. The PCI stack provides three ways to disable MSIs:h]hqSeveral PCI chipsets or devices are known not to support MSIs. The PCI stack provides three ways to disable MSIs:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjhhubhenumerated_list)}(hhh](h list_item)}(hgloballyh]j})}(hjh]hglobally}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h'on all devices behind a specific bridgeh]j})}(hjh]h'on all devices behind a specific bridge}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hon a single device h]j})}(hon a single deviceh]hon a single device}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1jhjhhhhhKubjH)}(hhh](jM)}(hDisabling MSIs globallyh]hDisabling MSIs globally}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jLhj hhhhhKubj})}(hXSome host chipsets simply don't support MSIs properly. If we're lucky, the manufacturer knows this and has indicated it in the ACPI FADT table. In this case, Linux automatically disables MSIs. Some boards don't include this information in the table and so we have to detect them ourselves. The complete list of these is found near the quirk_disable_all_msi() function in drivers/pci/quirks.c.h]hXSome host chipsets simply don’t support MSIs properly. If we’re lucky, the manufacturer knows this and has indicated it in the ACPI FADT table. In this case, Linux automatically disables MSIs. Some boards don’t include this information in the table and so we have to detect them ourselves. The complete list of these is found near the quirk_disable_all_msi() function in drivers/pci/quirks.c.}(hj- hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhj hhubj})}(hXIf you have a board which has problems with MSIs, you can pass pci=nomsi on the kernel command line to disable MSIs on all devices. It would be in your best interests to report the problem to linux-pci@vger.kernel.org including a full 'lspci -v' so we can add the quirks to the kernel.h](hIf you have a board which has problems with MSIs, you can pass pci=nomsi on the kernel command line to disable MSIs on all devices. It would be in your best interests to report the problem to }(hj; hhhNhNubh reference)}(hlinux-pci@vger.kernel.orgh]hlinux-pci@vger.kernel.org}(hjE hhhNhNubah}(h]h ]h"]h$]h&]refuri mailto:linux-pci@vger.kernel.orguh1jC hj; ubhH including a full ‘lspci -v’ so we can add the quirks to the kernel.}(hj; hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hhhKhj hhubeh}(h]disabling-msis-globallyah ]h"]disabling msis globallyah$]h&]uh1jGhjhhhhhKubjH)}(hhh](jM)}(hDisabling MSIs below a bridgeh]hDisabling MSIs below a bridge}(hjj hhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjg hhhhhKubj})}(hSome PCI bridges are not able to route MSIs between buses properly. In this case, MSIs must be disabled on all devices behind the bridge.h]hSome PCI bridges are not able to route MSIs between buses properly. In this case, MSIs must be disabled on all devices behind the bridge.}(hjx hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjg hhubj})}(hXSome bridges allow you to enable MSIs by changing some bits in their PCI configuration space (especially the Hypertransport chipsets such as the nVidia nForce and Serverworks HT2000). As with host chipsets, Linux mostly knows about them and automatically enables MSIs if it can. If you have a bridge unknown to Linux, you can enable MSIs in configuration space using whatever method you know works, then enable MSIs on that bridge by doing::h]hXSome bridges allow you to enable MSIs by changing some bits in their PCI configuration space (especially the Hypertransport chipsets such as the nVidia nForce and Serverworks HT2000). As with host chipsets, Linux mostly knows about them and automatically enables MSIs if it can. If you have a bridge unknown to Linux, you can enable MSIs in configuration space using whatever method you know works, then enable MSIs on that bridge by doing:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjg hhubj)}(h-echo 1 > /sys/bus/pci/devices/$bridge/msi_bush]h-echo 1 > /sys/bus/pci/devices/$bridge/msi_bus}hj sbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjg hhubj})}(hPwhere $bridge is the PCI address of the bridge you've enabled (eg 0000:00:0e.0).h]hRwhere $bridge is the PCI address of the bridge you’ve enabled (eg 0000:00:0e.0).}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjg hhubj})}(hTo disable MSIs, echo 0 instead of 1. Changing this value should be done with caution as it could break interrupt handling for all devices below this bridge.h]hTo disable MSIs, echo 0 instead of 1. Changing this value should be done with caution as it could break interrupt handling for all devices below this bridge.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhKhjg hhubj})}(hYAgain, please notify linux-pci@vger.kernel.org of any bridges that need special handling.h](hAgain, please notify }(hj hhhNhNubjD )}(hlinux-pci@vger.kernel.orgh]hlinux-pci@vger.kernel.org}(hj hhhNhNubah}(h]h ]h"]h$]h&]refuri mailto:linux-pci@vger.kernel.orguh1jC hj ubh+ of any bridges that need special handling.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hhhMhjg hhubeh}(h]disabling-msis-below-a-bridgeah ]h"]disabling msis below a bridgeah$]h&]uh1jGhjhhhhhKubjH)}(hhh](jM)}(h!Disabling MSIs on a single deviceh]h!Disabling MSIs on a single device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jLhj hhhhhMubj})}(hXXSome devices are known to have faulty MSI implementations. Usually this is handled in the individual device driver, but occasionally it's necessary to handle this with a quirk. Some drivers have an option to disable use of MSI. While this is a convenient workaround for the driver author, it is not good practice, and should not be emulated.h]hXZSome devices are known to have faulty MSI implementations. Usually this is handled in the individual device driver, but occasionally it’s necessary to handle this with a quirk. Some drivers have an option to disable use of MSI. While this is a convenient workaround for the driver author, it is not good practice, and should not be emulated.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhM hj hhubeh}(h]!disabling-msis-on-a-single-deviceah ]h"]!disabling msis on a single deviceah$]h&]uh1jGhjhhhhhMubjH)}(hhh](jM)}(h)Finding why MSIs are disabled on a deviceh]h)Finding why MSIs are disabled on a device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jLhj hhhhhMubj})}(hX9From the above three sections, you can see that there are many reasons why MSIs may not be enabled for a given device. Your first step should be to examine your dmesg carefully to determine whether MSIs are enabled for your machine. You should also check your .config to be sure you have enabled CONFIG_PCI_MSI.h]hX9From the above three sections, you can see that there are many reasons why MSIs may not be enabled for a given device. Your first step should be to examine your dmesg carefully to determine whether MSIs are enabled for your machine. You should also check your .config to be sure you have enabled CONFIG_PCI_MSI.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhMhj hhubj})}(hXThen, 'lspci -t' gives the list of bridges above a device. Reading `/sys/bus/pci/devices/*/msi_bus` will tell you whether MSIs are enabled (1) or disabled (0). If 0 is found in any of the msi_bus files belonging to bridges between the PCI root and the device, MSIs are disabled.h](hGThen, ‘lspci -t’ gives the list of bridges above a device. Reading }(hj. hhhNhNubhtitle_reference)}(h `/sys/bus/pci/devices/*/msi_bus`h]h/sys/bus/pci/devices/*/msi_bus}(hj8 hhhNhNubah}(h]h ]h"]h$]h&]uh1j6 hj. ubh will tell you whether MSIs are enabled (1) or disabled (0). If 0 is found in any of the msi_bus files belonging to bridges between the PCI root and the device, MSIs are disabled.}(hj. hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hhhMhj hhubj})}(hIt is also worth checking the device driver to see whether it supports MSIs. For example, it may contain calls to pci_alloc_irq_vectors() with the PCI_IRQ_MSI or PCI_IRQ_MSIX flags.h]hIt is also worth checking the device driver to see whether it supports MSIs. For example, it may contain calls to pci_alloc_irq_vectors() with the PCI_IRQ_MSI or PCI_IRQ_MSIX flags.}(hjP hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hhhMhj hhubeh}(h])finding-why-msis-are-disabled-on-a-deviceah ]h"])finding why msis are disabled on a deviceah$]h&]uh1jGhjhhhhhMubeh}(h] msi-quirksah ]h"] msi quirksah$]h&]uh1jGhjIhhhhhKubjH)}(hhh](jM)}(h#List of device drivers MSI(-X) APIsh]h#List of device drivers MSI(-X) APIs}(hjq hhhNhNubah}(h]h ]h"]h$]h&]uh1jLhjn hhhhhM#ubj})}(hThe PCI/MSI subsystem has a dedicated C file for its exported device driver APIs — `drivers/pci/msi/api.c`. The following functions are exported:h](hUThe PCI/MSI subsystem has a dedicated C file for its exported device driver APIs — }(hj hhhNhNubj7 )}(h`drivers/pci/msi/api.c`h]hdrivers/pci/msi/api.c}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j6 hj ubh'. The following functions are exported:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hhhM%hjn hhubhindex)}(hhh]h}(h]h ]h"]h$]h&]entries](singlepci_enable_msi (C function)c.pci_enable_msihNtauh1j hjn hhhNhNubhdesc)}(hhh](hdesc_signature)}(h(int pci_enable_msi (struct pci_dev *dev)h]hdesc_signature_line)}(h'int pci_enable_msi(struct pci_dev *dev)h](hdesc_sig_keyword_type)}(hinth]hint}(hj hhhNhNubah}(h]h ]ktah"]h$]h&]uh1j hj hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKubhdesc_sig_space)}(h h]h }(hj hhhNhNubah}(h]h ]wah"]h$]h&]uh1j hj hhhj hKubh desc_name)}(hpci_enable_msih]h desc_sig_name)}(hpci_enable_msih]hpci_enable_msi}(hj hhhNhNubah}(h]h ]nah"]h$]h&]uh1j hj ubah}(h]h ](sig-namedescnameeh"]h$]h&]hhuh1j hj hhhj hKubhdesc_parameterlist)}(h(struct pci_dev *dev)h]hdesc_parameter)}(hstruct pci_dev *devh](hdesc_sig_keyword)}(hstructh]hstruct}(hj hhhNhNubah}(h]h ]kah"]h$]h&]uh1j hj ubj )}(h h]h }(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hj1 hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj. ubah}(h]h ]h"]h$]h&] refdomaincreftype identifier reftargetj3 modnameN classnameN c:parent_keysphinx.domains.c LookupKey)}data]jM ASTIdentifier)}jH j sbc.pci_enable_msiasbuh1hhj ubj )}(h h]h }(hjZ hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubhdesc_sig_punctuation)}(h*h]h*}(hjj hhhNhNubah}(h]h ]pah"]h$]h&]uh1jh hj ubj )}(hdevh]hdev}(hjy hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj ubah}(h]h ]h"]h$]h&]hhuh1j hj hhhj hKubeh}(h]h ]h"]h$]h&]hh add_permalinkuh1j sphinx_line_type declaratorhj hhhj hKubah}(h]j ah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1j hj hKhj hhubh desc_content)}(hhh]j})}(h#Enable MSI interrupt mode on deviceh]h#Enable MSI interrupt mode on device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj hhubah}(h]h ]h"]h$]h&]uh1j hj hhhj hKubeh}(h]h ](jF functioneh"]h$]h&]domainjF objtypej desctypej noindex noindexentrynocontentsentryuh1j hhhjn hNhNubh container)}(hX**Parameters** ``struct pci_dev *dev`` the PCI device to operate on **Description** Legacy device driver API to enable MSI interrupts mode on device and allocate a single interrupt vector. On success, the allocated vector Linux IRQ will be saved at **dev->irq**. The driver must invoke pci_disable_msi() on cleanup. **NOTE** The newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead. **Return** 0 on success, errno otherwiseh](j})}(h**Parameters**h]hstrong)}(hj h]h Parameters}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj ubhdefinition_list)}(hhh]hdefinition_list_item)}(h5``struct pci_dev *dev`` the PCI device to operate on h](hterm)}(h``struct pci_dev *dev``h]hliteral)}(hj h]hstruct pci_dev *dev}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj ubh definition)}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj hKhj ubah}(h]h ]h"]h$]h&]uh1j hj ubeh}(h]h ]h"]h$]h&]uh1j hj hKhj ubah}(h]h ]h"]h$]h&]uh1j hj ubj})}(h**Description**h]j )}(hj= h]h Description}(hj? hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj; ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj ubj})}(hLegacy device driver API to enable MSI interrupts mode on device and allocate a single interrupt vector. On success, the allocated vector Linux IRQ will be saved at **dev->irq**. The driver must invoke pci_disable_msi() on cleanup.h](hLegacy device driver API to enable MSI interrupts mode on device and allocate a single interrupt vector. On success, the allocated vector Linux IRQ will be saved at }(hjS hhhNhNubj )}(h **dev->irq**h]hdev->irq}(hj[ hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjS ubh6. The driver must invoke pci_disable_msi() on cleanup.}(hjS hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj ubj})}(h**NOTE**h]j )}(hjv h]hNOTE}(hjx hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjt ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj ubj})}(hhThe newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead.h]hhThe newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj ubj})}(h **Return**h]j )}(hj h]hReturn}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj ubj})}(h0 on success, errno otherwiseh]h0 on success, errno otherwise}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_disable_msi (C function)c.pci_disable_msihNtauh1j hjn hhhNhNubj )}(hhh](j )}(h*void pci_disable_msi (struct pci_dev *dev)h]j )}(h)void pci_disable_msi(struct pci_dev *dev)h](j )}(hvoidh]hvoid}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK3ubj )}(h h]h }(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj hhhj hK3ubj )}(hpci_disable_msih]j )}(hpci_disable_msih]hpci_disable_msi}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubah}(h]h ](j j eh"]h$]h&]hhuh1j hj hhhj hK3ubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubj )}(h h]h }(hj, hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hj= hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj: ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetj? modnameN classnameNjL jO )}jR ]jU )}jH j sbc.pci_disable_msiasbuh1hhj ubj )}(h h]h }(hj] hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubji )}(hjl h]h*}(hjk hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hj ubj )}(hdevh]hdev}(hjx hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj ubah}(h]h ]h"]h$]h&]hhuh1j hj hhhj hK3ubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj hhhj hK3ubah}(h]j ah ](j j eh"]h$]h&]j j )j huh1j hj hK3hj hhubj )}(hhh]j})}(h$Disable MSI interrupt mode on deviceh]h$Disable MSI interrupt mode on device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK(hj hhubah}(h]h ]h"]h$]h&]uh1j hj hhhj hK3ubeh}(h]h ](jF functioneh"]h$]h&]j jF j j j j j j j uh1j hhhjn hNhNubj )}(hX**Parameters** ``struct pci_dev *dev`` the PCI device to operate on **Description** Legacy device driver API to disable MSI interrupt mode on device, free earlier allocated interrupt vectors, and restore INTx emulation. The PCI device Linux IRQ (**dev->irq**) is restored to its default pin-assertion IRQ. This is the cleanup pair of pci_enable_msi(). **NOTE** The newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead.h](j})}(h**Parameters**h]j )}(hj h]h Parameters}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK,hj ubj )}(hhh]j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hj h]hstruct pci_dev *dev}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK)hj ubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj hK)hj ubah}(h]h ]h"]h$]h&]uh1j hj ubeh}(h]h ]h"]h$]h&]uh1j hj hK)hj ubah}(h]h ]h"]h$]h&]uh1j hj ubj})}(h**Description**h]j )}(hjh]h Description}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK+hj ubj})}(hX Legacy device driver API to disable MSI interrupt mode on device, free earlier allocated interrupt vectors, and restore INTx emulation. The PCI device Linux IRQ (**dev->irq**) is restored to its default pin-assertion IRQ. This is the cleanup pair of pci_enable_msi().h](hLegacy device driver API to disable MSI interrupt mode on device, free earlier allocated interrupt vectors, and restore INTx emulation. The PCI device Linux IRQ (}(hj4hhhNhNubj )}(h **dev->irq**h]hdev->irq}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj4ubh]) is restored to its default pin-assertion IRQ. This is the cleanup pair of pci_enable_msi().}(hj4hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK+hj ubj})}(h**NOTE**h]j )}(hjWh]hNOTE}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjUubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK0hj ubj})}(hhThe newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead.h]hhThe newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead.}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK0hj ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_msix_vec_count (C function)c.pci_msix_vec_counthNtauh1j hjn hhhNhNubj )}(hhh](j )}(h,int pci_msix_vec_count (struct pci_dev *dev)h]j )}(h+int pci_msix_vec_count(struct pci_dev *dev)h](j )}(hinth]hint}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKGubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhjhKGubj )}(hpci_msix_vec_counth]j )}(hpci_msix_vec_counth]hpci_msix_vec_count}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ](j j eh"]h$]h&]hhuh1j hjhhhjhKGubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjmodnameN classnameNjL jO )}jR ]jU )}jH jsbc.pci_msix_vec_countasbuh1hhjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubji )}(hjl h]h*}(hj%hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjubj )}(hdevh]hdev}(hj2hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubah}(h]h ]h"]h$]h&]hhuh1j hjhhhjhKGubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjhhhjhKGubah}(h]jah ](j j eh"]h$]h&]j j )j huh1j hjhKGhjhhubj )}(hhh]j})}(h/Get number of MSI-X interrupt vectors on deviceh]h/Get number of MSI-X interrupt vectors on device}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK@hjYhhubah}(h]h ]h"]h$]h&]uh1j hjhhhjhKGubeh}(h]h ](jF functioneh"]h$]h&]j jF j jtj jtj j j uh1j hhhjn hNhNubj )}(hX**Parameters** ``struct pci_dev *dev`` the PCI device to operate on **Return** number of MSI-X interrupt vectors available on this device (i.e., the device's MSI-X capability structure "table size"), -EINVAL if the device is not MSI-X capable, other errnos otherwise.h](j})}(h**Parameters**h]j )}(hj~h]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hj|ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKDhjxubj )}(hhh]j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjh]hstruct pci_dev *dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKAhjubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjhKAhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKAhjubah}(h]h ]h"]h$]h&]uh1j hjxubj})}(h **Return**h]j )}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKChjxubj})}(hnumber of MSI-X interrupt vectors available on this device (i.e., the device's MSI-X capability structure "table size"), -EINVAL if the device is not MSI-X capable, other errnos otherwise.h]hnumber of MSI-X interrupt vectors available on this device (i.e., the device’s MSI-X capability structure “table size”), -EINVAL if the device is not MSI-X capable, other errnos otherwise.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKChjxubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j "pci_enable_msix_range (C function)c.pci_enable_msix_rangehNtauh1j hjn hhhNhNubj )}(hhh](j )}(hcint pci_enable_msix_range (struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec)h]j )}(hbint pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec)h](j )}(hinth]hint}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKlubj )}(h h]h }(hj,hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhj+hKlubj )}(hpci_enable_msix_rangeh]j )}(hpci_enable_msix_rangeh]hpci_enable_msix_range}(hj>hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj:ubah}(h]h ](j j eh"]h$]h&]hhuh1j hjhhhj+hKlubj )}(hI(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec)h](j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hjZhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjVubj )}(h h]h }(hjghhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjVubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjxhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjuubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjzmodnameN classnameNjL jO )}jR ]jU )}jH j@sbc.pci_enable_msix_rangeasbuh1hhjVubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjVubji )}(hjl h]h*}(hjhhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjVubj )}(hdevh]hdev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjVubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjRubj )}(hstruct msix_entry *entriesh](j )}(hj h]hstruct}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubh)}(hhh]j )}(h msix_entryh]h msix_entry}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjmodnameN classnameNjL jO )}jR ]jc.pci_enable_msix_rangeasbuh1hhjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubji )}(hjl h]h*}(hjhhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjubj )}(hentriesh]hentries}(hj#hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjRubj )}(h int minvech](j )}(hinth]hint}(hj<hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj8ubj )}(h h]h }(hjJhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj8ubj )}(hminvech]hminvec}(hjXhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj8ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjRubj )}(h int maxvech](j )}(hinth]hint}(hjqhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjmubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjmubj )}(hmaxvech]hmaxvec}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjmubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjRubeh}(h]h ]h"]h$]h&]hhuh1j hjhhhj+hKlubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjhhhj+hKlubah}(h]jah ](j j eh"]h$]h&]j j )j huh1j hj+hKlhjhhubj )}(hhh]j})}(h%Enable MSI-X interrupt mode on deviceh]h%Enable MSI-X interrupt mode on device}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKThjhhubah}(h]h ]h"]h$]h&]uh1j hjhhhj+hKlubeh}(h]h ](jF functioneh"]h$]h&]j jF j jj jj j j uh1j hhhjn hNhNubj )}(hX**Parameters** ``struct pci_dev *dev`` the PCI device to operate on ``struct msix_entry *entries`` input/output parameter, array of MSI-X configuration entries ``int minvec`` minimum required number of MSI-X vectors ``int maxvec`` maximum desired number of MSI-X vectors **Description** Legacy device driver API to enable MSI-X interrupt mode on device and configure its MSI-X capability structure as appropriate. The passed **entries** array must have each of its members "entry" field set to a desired (valid) MSI-X vector number, where the range of valid MSI-X vector numbers can be queried through pci_msix_vec_count(). If successful, the driver must invoke pci_disable_msix() on cleanup. **NOTE** The newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead. **Return** number of MSI-X vectors allocated (which might be smaller than **maxvecs**), where Linux IRQ numbers for such allocated vectors are saved back in the **entries** array elements' "vector" field. Return -ENOSPC if less than **minvecs** interrupt vectors are available. Return -EINVAL if one of the passed **entries** members "entry" field was invalid or a duplicate, or if plain MSI interrupts mode was earlier enabled on device. Return other errnos otherwise.h](j})}(h**Parameters**h]j )}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKXhjubj )}(hhh](j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjh]hstruct pci_dev *dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKUhjubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj hKUhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hj hKUhjubj )}(h\``struct msix_entry *entries`` input/output parameter, array of MSI-X configuration entries h](j )}(h``struct msix_entry *entries``h]j )}(hj1h]hstruct msix_entry *entries}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj/ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKVhj+ubj )}(hhh]j})}(hh]hReturn}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj<ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKdhjubj})}(hXnumber of MSI-X vectors allocated (which might be smaller than **maxvecs**), where Linux IRQ numbers for such allocated vectors are saved back in the **entries** array elements' "vector" field. Return -ENOSPC if less than **minvecs** interrupt vectors are available. Return -EINVAL if one of the passed **entries** members "entry" field was invalid or a duplicate, or if plain MSI interrupts mode was earlier enabled on device. Return other errnos otherwise.h](h?number of MSI-X vectors allocated (which might be smaller than }(hjThhhNhNubj )}(h **maxvecs**h]hmaxvecs}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjTubhL), where Linux IRQ numbers for such allocated vectors are saved back in the }(hjThhhNhNubj )}(h **entries**h]hentries}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjTubhC array elements’ “vector” field. Return -ENOSPC if less than }(hjThhhNhNubj )}(h **minvecs**h]hminvecs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjTubhF interrupt vectors are available. Return -EINVAL if one of the passed }(hjThhhNhNubj )}(h **entries**h]hentries}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjTubh members “entry” field was invalid or a duplicate, or if plain MSI interrupts mode was earlier enabled on device. Return other errnos otherwise.}(hjThhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKdhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j #pci_msix_can_alloc_dyn (C function)c.pci_msix_can_alloc_dynhNtauh1j hjn hhhNhNubj )}(hhh](j )}(h1bool pci_msix_can_alloc_dyn (struct pci_dev *dev)h]j )}(h0bool pci_msix_can_alloc_dyn(struct pci_dev *dev)h](j )}(hboolh]hbool}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chK{ubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhjhK{ubj )}(hpci_msix_can_alloc_dynh]j )}(hpci_msix_can_alloc_dynh]hpci_msix_can_alloc_dyn}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ](j j eh"]h$]h&]hhuh1j hjhhhjhK{ubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubh)}(hhh]j )}(hpci_devh]hpci_dev}(hj&hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj#ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetj(modnameN classnameNjL jO )}jR ]jU )}jH jsbc.pci_msix_can_alloc_dynasbuh1hhjubj )}(h h]h }(hjFhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubji )}(hjl h]h*}(hjThhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjubj )}(hdevh]hdev}(hjahhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubah}(h]h ]h"]h$]h&]hhuh1j hjhhhjhK{ubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjhhhjhK{ubah}(h]jah ](j j eh"]h$]h&]j j )j huh1j hjhK{hjhhubj )}(hhh]j})}(hBQuery whether dynamic allocation after enabling MSI-X is supportedh]hBQuery whether dynamic allocation after enabling MSI-X is supported}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKthjhhubah}(h]h ]h"]h$]h&]uh1j hjhhhjhK{ubeh}(h]h ](jF functioneh"]h$]h&]j jF j jj jj j j uh1j hhhjn hNhNubj )}(hr**Parameters** ``struct pci_dev *dev`` PCI device to operate on **Return** True if supported, false otherwiseh](j})}(h**Parameters**h]j )}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKxhjubj )}(hhh]j )}(h1``struct pci_dev *dev`` PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjh]hstruct pci_dev *dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKwhjubj )}(hhh]j})}(hPCI device to operate onh]hPCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjhKwhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKwhjubah}(h]h ]h"]h$]h&]uh1j hjubj})}(h **Return**h]j )}(hjh]hReturn}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKyhjubj})}(h"True if supported, false otherwiseh]h"True if supported, false otherwise}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKyhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j "pci_msix_alloc_irq_at (C function)c.pci_msix_alloc_irq_athNtauh1j hjn hhhNhNubj )}(hhh](j )}(hwstruct msi_map pci_msix_alloc_irq_at (struct pci_dev *dev, unsigned int index, const struct irq_affinity_desc *affdesc)h]j )}(hvstruct msi_map pci_msix_alloc_irq_at(struct pci_dev *dev, unsigned int index, const struct irq_affinity_desc *affdesc)h](j )}(hj h]hstruct}(hjLhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjHhhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKubj )}(h h]h }(hjZhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjHhhhjYhKubh)}(hhh]j )}(hmsi_maph]hmsi_map}(hjkhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjmmodnameN classnameNjL jO )}jR ]jU )}jH pci_msix_alloc_irq_atsbc.pci_msix_alloc_irq_atasbuh1hhjHhhhjYhKubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjHhhhjYhKubj )}(hpci_msix_alloc_irq_ath]j )}(hjh]hpci_msix_alloc_irq_at}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ](j j eh"]h$]h&]hhuh1j hjHhhhjYhKubj )}(hR(struct pci_dev *dev, unsigned int index, const struct irq_affinity_desc *affdesc)h](j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjmodnameN classnameNjL jO )}jR ]jc.pci_msix_alloc_irq_atasbuh1hhjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubji )}(hjl h]h*}(hjhhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjubj )}(hdevh]hdev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(hunsigned int indexh](j )}(hunsignedh]hunsigned}(hj)hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%ubj )}(h h]h }(hj7hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%ubj )}(hinth]hint}(hjEhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%ubj )}(h h]h }(hjShhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%ubj )}(hindexh]hindex}(hjahhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(h'const struct irq_affinity_desc *affdesch](j )}(hconsth]hconst}(hjzhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjvubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjvubj )}(hj h]hstruct}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjvubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjvubh)}(hhh]j )}(hirq_affinity_desch]hirq_affinity_desc}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjmodnameN classnameNjL jO )}jR ]jc.pci_msix_alloc_irq_atasbuh1hhjvubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjvubji )}(hjl h]h*}(hjhhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjvubj )}(haffdesch]haffdesc}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjvubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubeh}(h]h ]h"]h$]h&]hhuh1j hjHhhhjYhKubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjDhhhjYhKubah}(h]j?ah ](j j eh"]h$]h&]j j )j huh1j hjYhKhjAhhubj )}(hhh]j})}(hgAllocate an MSI-X interrupt after enabling MSI-X at a given MSI-X vector index or any free vector indexh]hgAllocate an MSI-X interrupt after enabling MSI-X at a given MSI-X vector index or any free vector index}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjhhubah}(h]h ]h"]h$]h&]uh1j hjAhhhjYhKubeh}(h]h ](jF functioneh"]h$]h&]j jF j j/j j/j j j uh1j hhhjn hNhNubj )}(hX@**Parameters** ``struct pci_dev *dev`` PCI device to operate on ``unsigned int index`` Index to allocate. If **index** == MSI_ANY_INDEX this allocates the next free index in the MSI-X table ``const struct irq_affinity_desc *affdesc`` Optional pointer to an affinity descriptor structure. NULL otherwise **Return** A struct msi_map On success msi_map::index contains the allocated index (>= 0) and msi_map::virq contains the allocated Linux interrupt number (> 0). On fail msi_map::index contains the error code and msi_map::virq is set to 0.h](j})}(h**Parameters**h]j )}(hj9h]h Parameters}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj7ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj3ubj )}(hhh](j )}(h1``struct pci_dev *dev`` PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjXh]hstruct pci_dev *dev}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjVubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjRubj )}(hhh]j})}(hPCI device to operate onh]hPCI device to operate on}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjmhKhjnubah}(h]h ]h"]h$]h&]uh1j hjRubeh}(h]h ]h"]h$]h&]uh1j hjmhKhjOubj )}(h~``unsigned int index`` Index to allocate. If **index** == MSI_ANY_INDEX this allocates the next free index in the MSI-X table h](j )}(h``unsigned int index``h]j )}(hjh]hunsigned int index}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh]j})}(hfIndex to allocate. If **index** == MSI_ANY_INDEX this allocates the next free index in the MSI-X tableh](hIndex to allocate. If }(hjhhhNhNubj )}(h **index**h]hindex}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubhG == MSI_ANY_INDEX this allocates the next free index in the MSI-X table}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjOubj )}(hq``const struct irq_affinity_desc *affdesc`` Optional pointer to an affinity descriptor structure. NULL otherwise h](j )}(h+``const struct irq_affinity_desc *affdesc``h]j )}(hjh]h'const struct irq_affinity_desc *affdesc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh]j})}(hDOptional pointer to an affinity descriptor structure. NULL otherwiseh]hDOptional pointer to an affinity descriptor structure. NULL otherwise}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjhKhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjOubeh}(h]h ]h"]h$]h&]uh1j hj3ubj})}(h **Return**h]j )}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj3ubj})}(hA struct msi_maph]hA struct msi_map}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj3ubh block_quote)}(hOn success msi_map::index contains the allocated index (>= 0) and msi_map::virq contains the allocated Linux interrupt number (> 0). On fail msi_map::index contains the error code and msi_map::virq is set to 0.h](j})}(hOn success msi_map::index contains the allocated index (>= 0) and msi_map::virq contains the allocated Linux interrupt number (> 0).h]hOn success msi_map::index contains the allocated index (>= 0) and msi_map::virq contains the allocated Linux interrupt number (> 0).}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj?ubj})}(hMOn fail msi_map::index contains the error code and msi_map::virq is set to 0.h]hMOn fail msi_map::index contains the error code and msi_map::virq is set to 0.}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj?ubeh}(h]h ]h"]h$]h&]uh1j=hjQhKhj3ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_msix_free_irq (C function)c.pci_msix_free_irqhNtauh1j hjn hhhNhNubj )}(hhh](j )}(h@void pci_msix_free_irq (struct pci_dev *dev, struct msi_map map)h]j )}(h?void pci_msix_free_irq(struct pci_dev *dev, struct msi_map map)h](j )}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhjhKubj )}(hpci_msix_free_irqh]j )}(hpci_msix_free_irqh]hpci_msix_free_irq}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ](j j eh"]h$]h&]hhuh1j hjhhhjhKubj )}(h)(struct pci_dev *dev, struct msi_map map)h](j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjmodnameN classnameNjL jO )}jR ]jU )}jH jsbc.pci_msix_free_irqasbuh1hhjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubji )}(hjl h]h*}(hjhhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjubj )}(hdevh]hdev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(hstruct msi_map maph](j )}(hj h]hstruct}(hj6hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj2ubj )}(h h]h }(hjChhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj2ubh)}(hhh]j )}(hmsi_maph]hmsi_map}(hjThhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjQubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjVmodnameN classnameNjL jO )}jR ]jc.pci_msix_free_irqasbuh1hhj2ubj )}(h h]h }(hjrhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj2ubj )}(hmaph]hmap}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj2ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubeh}(h]h ]h"]h$]h&]hhuh1j hjhhhjhKubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjhhhjhKubah}(h]jzah ](j j eh"]h$]h&]j j )j huh1j hjhKhj|hhubj )}(hhh]j})}(h1Free an interrupt on a PCI/MSI-X interrupt domainh]h1Free an interrupt on a PCI/MSI-X interrupt domain}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjhhubah}(h]h ]h"]h$]h&]uh1j hj|hhhjhKubeh}(h]h ](jF functioneh"]h$]h&]j jF j jj jj j j uh1j hhhjn hNhNubj )}(h**Parameters** ``struct pci_dev *dev`` The PCI device to operate on ``struct msi_map map`` A struct msi_map describing the interrupt to free **Description** Undo an interrupt vector allocation. Does not disable MSI-X.h](j})}(h**Parameters**h]j )}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh](j )}(h5``struct pci_dev *dev`` The PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjh]hstruct pci_dev *dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh]j})}(hThe PCI device to operate onh]hThe PCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjhKhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjubj )}(hI``struct msi_map map`` A struct msi_map describing the interrupt to free h](j )}(h``struct msi_map map``h]j )}(hj$h]hstruct msi_map map}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj"ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh]j})}(h1A struct msi_map describing the interrupt to freeh]h1A struct msi_map describing the interrupt to free}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj9hKhj:ubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hj9hKhjubeh}(h]h ]h"]h$]h&]uh1j hjubj})}(h**Description**h]j )}(hj_h]h Description}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1j hj]ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj})}(hirq**) is restored to its default pin assertion IRQ. This is the cleanup pair of pci_enable_msix_range(). **NOTE** The newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead.h](j})}(h**Parameters**h]j )}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh]j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjh]hstruct pci_dev *dev}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjhKhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjubah}(h]h ]h"]h$]h&]uh1j hjubj})}(h**Description**h]j )}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj})}(hX Legacy device driver API to disable MSI-X interrupt mode on device, free earlier-allocated interrupt vectors, and restore INTx. The PCI device Linux IRQ (**dev->irq**) is restored to its default pin assertion IRQ. This is the cleanup pair of pci_enable_msix_range().h](hLegacy device driver API to disable MSI-X interrupt mode on device, free earlier-allocated interrupt vectors, and restore INTx. The PCI device Linux IRQ (}(hjhhhNhNubj )}(h **dev->irq**h]hdev->irq}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubhd) is restored to its default pin assertion IRQ. This is the cleanup pair of pci_enable_msix_range().}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj})}(h**NOTE**h]j )}(hjh]hNOTE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj})}(hhThe newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead.h]hhThe newer pci_alloc_irq_vectors() / pci_free_irq_vectors() API pair should, in general, be used instead.}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j "pci_alloc_irq_vectors (C function)c.pci_alloc_irq_vectorshNtauh1j hjn hhhNhNubj )}(hhh](j )}(hqint pci_alloc_irq_vectors (struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags)h]j )}(hpint pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags)h](j )}(hinth]hint}(hj^hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjZhhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKubj )}(h h]h }(hjmhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjZhhhjlhKubj )}(hpci_alloc_irq_vectorsh]j )}(hpci_alloc_irq_vectorsh]hpci_alloc_irq_vectors}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj{ubah}(h]h ](j j eh"]h$]h&]hhuh1j hjZhhhjlhKubj )}(hW(struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags)h](j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjmodnameN classnameNjL jO )}jR ]jU )}jH jsbc.pci_alloc_irq_vectorsasbuh1hhjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubji )}(hjl h]h*}(hjhhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjubj )}(hdevh]hdev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(hunsigned int min_vecsh](j )}(hunsignedh]hunsigned}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubj )}(hinth]hint}(hj)hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubj )}(h h]h }(hj7hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubj )}(hmin_vecsh]hmin_vecs}(hjEhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(hunsigned int max_vecsh](j )}(hunsignedh]hunsigned}(hj^hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjZubj )}(h h]h }(hjlhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjZubj )}(hinth]hint}(hjzhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjZubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjZubj )}(hmax_vecsh]hmax_vecs}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjZubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(hunsigned int flagsh](j )}(hunsignedh]hunsigned}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(hinth]hint}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(hflagsh]hflags}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubeh}(h]h ]h"]h$]h&]hhuh1j hjZhhhjlhKubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjVhhhjlhKubah}(h]jQah ](j j eh"]h$]h&]j j )j huh1j hjlhKhjShhubj )}(hhh]j})}(h*Allocate multiple device interrupt vectorsh]h*Allocate multiple device interrupt vectors}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjhhubah}(h]h ]h"]h$]h&]uh1j hjShhhjlhKubeh}(h]h ](jF functioneh"]h$]h&]j jF j j)j j)j j j uh1j hhhjn hNhNubj )}(hX~**Parameters** ``struct pci_dev *dev`` the PCI device to operate on ``unsigned int min_vecs`` minimum required number of vectors (must be >= 1) ``unsigned int max_vecs`` maximum desired number of vectors ``unsigned int flags`` One or more of: * ``PCI_IRQ_MSIX`` Allow trying MSI-X vector allocations * ``PCI_IRQ_MSI`` Allow trying MSI vector allocations * ``PCI_IRQ_INTX`` Allow trying INTx interrupts, if and only if **min_vecs** == 1 * ``PCI_IRQ_AFFINITY`` Auto-manage IRQs affinity by spreading the vectors around available CPUs **Description** Allocate up to **max_vecs** interrupt vectors on device. MSI-X irq vector allocation has a higher precedence over plain MSI, which has a higher precedence over legacy INTx emulation. Upon a successful allocation, the caller should use pci_irq_vector() to get the Linux IRQ number to be passed to request_threaded_irq(). The driver must call pci_free_irq_vectors() on cleanup. **Return** number of allocated vectors (which might be smaller than **max_vecs**), -ENOSPC if less than **min_vecs** interrupt vectors are available, other errnos otherwise.h](j})}(h**Parameters**h]j )}(hj3h]h Parameters}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj1ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj-ubj )}(hhh](j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjRh]hstruct pci_dev *dev}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1j hjPubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjLubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjghKhjhubah}(h]h ]h"]h$]h&]uh1j hjLubeh}(h]h ]h"]h$]h&]uh1j hjghKhjIubj )}(hL``unsigned int min_vecs`` minimum required number of vectors (must be >= 1) h](j )}(h``unsigned int min_vecs``h]j )}(hjh]hunsigned int min_vecs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh]j})}(h1minimum required number of vectors (must be >= 1)h]h1minimum required number of vectors (must be >= 1)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjhKhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjIubj )}(h<``unsigned int max_vecs`` maximum desired number of vectors h](j )}(h``unsigned int max_vecs``h]j )}(hjh]hunsigned int max_vecs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh]j})}(h!maximum desired number of vectorsh]h!maximum desired number of vectors}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjhKhjubah}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjIubj )}(hX```unsigned int flags`` One or more of: * ``PCI_IRQ_MSIX`` Allow trying MSI-X vector allocations * ``PCI_IRQ_MSI`` Allow trying MSI vector allocations * ``PCI_IRQ_INTX`` Allow trying INTx interrupts, if and only if **min_vecs** == 1 * ``PCI_IRQ_AFFINITY`` Auto-manage IRQs affinity by spreading the vectors around available CPUs h](j )}(h``unsigned int flags``h]j )}(hjh]hunsigned int flags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubj )}(hhh](j})}(hOne or more of:h]hOne or more of:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubh bullet_list)}(hhh](j)}(h;``PCI_IRQ_MSIX`` Allow trying MSI-X vector allocationsh]j})}(hj,h](j )}(h``PCI_IRQ_MSIX``h]h PCI_IRQ_MSIX}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj.ubh+ Allow trying MSI-X vector allocations}(hj.hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj*ubah}(h]h ]h"]h$]h&]uh1jhj'ubj)}(h:``PCI_IRQ_MSI`` Allow trying MSI vector allocations h]j})}(h9``PCI_IRQ_MSI`` Allow trying MSI vector allocationsh](j )}(h``PCI_IRQ_MSI``h]h PCI_IRQ_MSI}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjTubh* Allow trying MSI vector allocations}(hjThhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjPubah}(h]h ]h"]h$]h&]uh1jhj'ubj)}(hU``PCI_IRQ_INTX`` Allow trying INTx interrupts, if and only if **min_vecs** == 1 h]j})}(hT``PCI_IRQ_INTX`` Allow trying INTx interrupts, if and only if **min_vecs** == 1h](j )}(h``PCI_IRQ_INTX``h]h PCI_IRQ_INTX}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hj{ubh3 Allow trying INTx interrupts, if and only if }(hj{hhhNhNubj )}(h **min_vecs**h]hmin_vecs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hj{ubh == 1}(hj{hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjwubah}(h]h ]h"]h$]h&]uh1jhj'ubj)}(h_``PCI_IRQ_AFFINITY`` Auto-manage IRQs affinity by spreading the vectors around available CPUs h]j})}(h^``PCI_IRQ_AFFINITY`` Auto-manage IRQs affinity by spreading the vectors around available CPUsh](j )}(h``PCI_IRQ_AFFINITY``h]hPCI_IRQ_AFFINITY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubhJ Auto-manage IRQs affinity by spreading the vectors around available CPUs}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjubah}(h]h ]h"]h$]h&]uh1jhj'ubeh}(h]h ]h"]h$]h&]bulletjl uh1j%hjIhKhjubeh}(h]h ]h"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjIubeh}(h]h ]h"]h$]h&]uh1j hj-ubj})}(h**Description**h]j )}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj-ubj})}(hAllocate up to **max_vecs** interrupt vectors on device. MSI-X irq vector allocation has a higher precedence over plain MSI, which has a higher precedence over legacy INTx emulation.h](hAllocate up to }(hj hhhNhNubj )}(h **max_vecs**h]hmax_vecs}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh interrupt vectors on device. MSI-X irq vector allocation has a higher precedence over plain MSI, which has a higher precedence over legacy INTx emulation.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj-ubj})}(hUpon a successful allocation, the caller should use pci_irq_vector() to get the Linux IRQ number to be passed to request_threaded_irq(). The driver must call pci_free_irq_vectors() on cleanup.h]hUpon a successful allocation, the caller should use pci_irq_vector() to get the Linux IRQ number to be passed to request_threaded_irq(). The driver must call pci_free_irq_vectors() on cleanup.}(hj) hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj-ubj})}(h **Return**h]j )}(hj: h]hReturn}(hj< hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj8 ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj-ubj})}(hnumber of allocated vectors (which might be smaller than **max_vecs**), -ENOSPC if less than **min_vecs** interrupt vectors are available, other errnos otherwise.h](h9number of allocated vectors (which might be smaller than }(hjP hhhNhNubj )}(h **max_vecs**h]hmax_vecs}(hjX hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjP ubh), -ENOSPC if less than }(hjP hhhNhNubj )}(h **min_vecs**h]hmin_vecs}(hjj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjP ubh9 interrupt vectors are available, other errnos otherwise.}(hjP hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj-ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j +pci_alloc_irq_vectors_affinity (C function) c.pci_alloc_irq_vectors_affinityhNtauh1j hjn hhhNhNubj )}(hhh](j )}(hint pci_alloc_irq_vectors_affinity (struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags, struct irq_affinity *affd)h]j )}(hint pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags, struct irq_affinity *affd)h](j )}(hinth]hint}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKubj )}(h h]h }(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj hhhj hKubj )}(hpci_alloc_irq_vectors_affinityh]j )}(hpci_alloc_irq_vectors_affinityh]hpci_alloc_irq_vectors_affinity}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubah}(h]h ](j j eh"]h$]h&]hhuh1j hj hhhj hKubj )}(hr(struct pci_dev *dev, unsigned int min_vecs, unsigned int max_vecs, unsigned int flags, struct irq_affinity *affd)h](j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubj )}(h h]h }(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetj!modnameN classnameNjL jO )}jR ]jU )}jH j sb c.pci_alloc_irq_vectors_affinityasbuh1hhj ubj )}(h h]h }(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubji )}(hjl h]h*}(hj,!hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hj ubj )}(hdevh]hdev}(hj9!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj ubj )}(hunsigned int min_vecsh](j )}(hunsignedh]hunsigned}(hjR!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjN!ubj )}(h h]h }(hj`!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjN!ubj )}(hinth]hint}(hjn!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjN!ubj )}(h h]h }(hj|!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjN!ubj )}(hmin_vecsh]hmin_vecs}(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjN!ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj ubj )}(hunsigned int max_vecsh](j )}(hunsignedh]hunsigned}(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj )}(h h]h }(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj )}(hinth]hint}(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj )}(h h]h }(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj )}(hmax_vecsh]hmax_vecs}(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj ubj )}(hunsigned int flagsh](j )}(hunsignedh]hunsigned}(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj )}(h h]h }(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj )}(hinth]hint}(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj )}(h h]h }(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj )}(hflagsh]hflags}(hj,"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj ubj )}(hstruct irq_affinity *affdh](j )}(hj h]hstruct}(hjE"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjA"ubj )}(h h]h }(hjR"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjA"ubh)}(hhh]j )}(h irq_affinityh]h irq_affinity}(hjc"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj`"ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetje"modnameN classnameNjL jO )}jR ]j! c.pci_alloc_irq_vectors_affinityasbuh1hhjA"ubj )}(h h]h }(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjA"ubji )}(hjl h]h*}(hj"hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hjA"ubj )}(haffdh]haffd}(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjA"ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj ubeh}(h]h ]h"]h$]h&]hhuh1j hj hhhj hKubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj hhhj hKubah}(h]j ah ](j j eh"]h$]h&]j j )j huh1j hj hKhj hhubj )}(hhh]j})}(hEAllocate multiple device interrupt vectors with affinity requirementsh]hEAllocate multiple device interrupt vectors with affinity requirements}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj"hhubah}(h]h ]h"]h$]h&]uh1j hj hhhj hKubeh}(h]h ](jF functioneh"]h$]h&]j jF j j"j j"j j j uh1j hhhjn hNhNubj )}(hX **Parameters** ``struct pci_dev *dev`` the PCI device to operate on ``unsigned int min_vecs`` minimum required number of vectors (must be >= 1) ``unsigned int max_vecs`` maximum desired number of vectors ``unsigned int flags`` allocation flags, as in pci_alloc_irq_vectors() ``struct irq_affinity *affd`` affinity requirements (can be ``NULL``). **Description** Same as pci_alloc_irq_vectors(), but with the extra **affd** parameter. Check that function docs, and :c:type:`struct irq_affinity `, for more details.h](j})}(h**Parameters**h]j )}(hj"h]h Parameters}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj"ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj"ubj )}(hhh](j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hj#h]hstruct pci_dev *dev}(hj #hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj#ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj#ubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj #hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj#hKhj#ubah}(h]h ]h"]h$]h&]uh1j hj#ubeh}(h]h ]h"]h$]h&]uh1j hj#hKhj"ubj )}(hL``unsigned int min_vecs`` minimum required number of vectors (must be >= 1) h](j )}(h``unsigned int min_vecs``h]j )}(hj@#h]hunsigned int min_vecs}(hjB#hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj>#ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj:#ubj )}(hhh]j})}(h1minimum required number of vectors (must be >= 1)h]h1minimum required number of vectors (must be >= 1)}(hjY#hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjU#hKhjV#ubah}(h]h ]h"]h$]h&]uh1j hj:#ubeh}(h]h ]h"]h$]h&]uh1j hjU#hKhj"ubj )}(h<``unsigned int max_vecs`` maximum desired number of vectors h](j )}(h``unsigned int max_vecs``h]j )}(hjy#h]hunsigned int max_vecs}(hj{#hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjw#ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjs#ubj )}(hhh]j})}(h!maximum desired number of vectorsh]h!maximum desired number of vectors}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj#hKhj#ubah}(h]h ]h"]h$]h&]uh1j hjs#ubeh}(h]h ]h"]h$]h&]uh1j hj#hKhj"ubj )}(hG``unsigned int flags`` allocation flags, as in pci_alloc_irq_vectors() h](j )}(h``unsigned int flags``h]j )}(hj#h]hunsigned int flags}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj#ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj#ubj )}(hhh]j})}(h/allocation flags, as in pci_alloc_irq_vectors()h]h/allocation flags, as in pci_alloc_irq_vectors()}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj#hKhj#ubah}(h]h ]h"]h$]h&]uh1j hj#ubeh}(h]h ]h"]h$]h&]uh1j hj#hKhj"ubj )}(hG``struct irq_affinity *affd`` affinity requirements (can be ``NULL``). h](j )}(h``struct irq_affinity *affd``h]j )}(hj#h]hstruct irq_affinity *affd}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj#ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj#ubj )}(hhh]j})}(h(affinity requirements (can be ``NULL``).h](haffinity requirements (can be }(hj$hhhNhNubj )}(h``NULL``h]hNULL}(hj $hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj$ubh).}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hj$hKhj$ubah}(h]h ]h"]h$]h&]uh1j hj#ubeh}(h]h ]h"]h$]h&]uh1j hj$hKhj"ubeh}(h]h ]h"]h$]h&]uh1j hj"ubj})}(h**Description**h]j )}(hj8$h]h Description}(hj:$hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj6$ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhj"ubj})}(hSame as pci_alloc_irq_vectors(), but with the extra **affd** parameter. Check that function docs, and :c:type:`struct irq_affinity `, for more details.h](h4Same as pci_alloc_irq_vectors(), but with the extra }(hjN$hhhNhNubj )}(h**affd**h]haffd}(hjV$hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjN$ubh* parameter. Check that function docs, and }(hjN$hhhNhNubh)}(h,:c:type:`struct irq_affinity `h]j )}(hjj$h]hstruct irq_affinity}(hjl$hhhNhNubah}(h]h ](xrefjF c-typeeh"]h$]h&]uh1j hjh$ubah}(h]h ]h"]h$]h&]refdoc PCI/msi-howto refdomainjF reftypetype refexplicitrefwarnjL jO )}jR ]sb reftarget irq_affinityuh1hhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chKhjN$ubh, for more details.}(hjN$hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hj$hKhj"ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_irq_vector (C function)c.pci_irq_vectorhNtauh1j hjn hhhNhNubj )}(hhh](j )}(h9int pci_irq_vector (struct pci_dev *dev, unsigned int nr)h]j )}(h8int pci_irq_vector(struct pci_dev *dev, unsigned int nr)h](j )}(hinth]hint}(hj$hhhNhNubah}(h]h ]j ah"]h$]h&(]uh1j hj$hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM9ubj )}(h h]h }(hj$hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj$hhhj$hM9ubj )}(hpci_irq_vectorh]j )}(hpci_irq_vectorh]hpci_irq_vector}(hj$hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj$ubah}(h]h ](j j eh"]h$]h&]hhuh1j hj$hhhj$hM9ubj )}(h&(struct pci_dev *dev, unsigned int nr)h](j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hj$hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj$ubj )}(h h]h }(hj%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj$ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hj%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetj%modnameN classnameNjL jO )}jR ]jU )}jH j$sbc.pci_irq_vectorasbuh1hhj$ubj )}(h h]h }(hj3%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj$ubji )}(hjl h]h*}(hjA%hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hj$ubj )}(hdevh]hdev}(hjN%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj$ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj$ubj )}(hunsigned int nrh](j )}(hunsignedh]hunsigned}(hjg%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjc%ubj )}(h h]h }(hju%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjc%ubj )}(hinth]hint}(hj%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjc%ubj )}(h h]h }(hj%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjc%ubj )}(hnrh]hnr}(hj%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjc%ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj$ubeh}(h]h ]h"]h$]h&]hhuh1j hj$hhhj$hM9ubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj$hhhj$hM9ubah}(h]j$ah ](j j eh"]h$]h&]j j )j huh1j hj$hM9hj$hhubj )}(hhh]j})}(h1Get Linux IRQ number of a device interrupt vectorh]h1Get Linux IRQ number of a device interrupt vector}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM.hj%hhubah}(h]h ]h"]h$]h&]uh1j hj$hhhj$hM9ubeh}(h]h ](jF functioneh"]h$]h&]j jF j j%j j%j j j uh1j hhhjn hNhNubj )}(hX**Parameters** ``struct pci_dev *dev`` the PCI device to operate on ``unsigned int nr`` device-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode: * MSI-X the index in the MSI-X vector table * MSI the index of the enabled MSI vectors * INTx must be 0 **Return** the Linux IRQ number, or -EINVAL if **nr** is out of rangeh](j})}(h**Parameters**h]j )}(hj%h]h Parameters}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj%ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM2hj%ubj )}(hhh](j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hj &h]hstruct pci_dev *dev}(hj &hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj&ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM/hj&ubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj#&hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj&hM/hj &ubah}(h]h ]h"]h$]h&]uh1j hj&ubeh}(h]h ]h"]h$]h&]uh1j hj&hM/hj&ubj )}(h``unsigned int nr`` device-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode: * MSI-X the index in the MSI-X vector table * MSI the index of the enabled MSI vectors * INTx must be 0 h](j )}(h``unsigned int nr``h]j )}(hjC&h]hunsigned int nr}(hjE&hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjA&ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM5hj=&ubj )}(hhh](j})}(hfdevice-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode:h]hfdevice-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode:}(hj\&hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM0hjY&ubj>)}(hw* MSI-X the index in the MSI-X vector table * MSI the index of the enabled MSI vectors * INTx must be 0 h]j&)}(hhh](j)}(h-MSI-X the index in the MSI-X vector tableh]j})}(hjt&h]h-MSI-X the index in the MSI-X vector table}(hjv&hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM3hjr&ubah}(h]h ]h"]h$]h&]uh1jhjo&ubj)}(h.MSI the index of the enabled MSI vectorsh]j})}(hj&h]h.MSI the index of the enabled MSI vectors}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM4hj&ubah}(h]h ]h"]h$]h&]uh1jhjo&ubj)}(hINTx must be 0 h]j})}(hINTx must be 0h]hINTx must be 0}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hjX&hM5hj&ubah}(h]h ]h"]h$]h&]uh1jhjo&ubeh}(h]h ]h"]h$]h&]jjl uh1j%hj&hM3hjk&ubah}(h]h ]h"]h$]h&]uh1j=hj&hM3hjY&ubeh}(h]h ]h"]h$]h&]uh1j hj=&ubeh}(h]h ]h"]h$]h&]uh1j hjX&hM5hj&ubeh}(h]h ]h"]h$]h&]uh1j hj%ubj})}(h **Return**h]j )}(hj&h]hReturn}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj&ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM7hj%ubj})}(h:the Linux IRQ number, or -EINVAL if **nr** is out of rangeh](h$the Linux IRQ number, or -EINVAL if }(hj&hhhNhNubj )}(h**nr**h]hnr}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj&ubh is out of range}(hj&hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chM7hj%ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j !pci_irq_get_affinity (C function)c.pci_irq_get_affinityhNtauh1j hjn hhhNhNubj )}(hhh](j )}(hIconst struct cpumask * pci_irq_get_affinity (struct pci_dev *dev, int nr)h]j )}(hGconst struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr)h](j )}(hj|h]hconst}(hj1'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-'hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMVubj )}(h h]h }(hj?'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-'hhhj>'hMVubj )}(hj h]hstruct}(hjM'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-'hhhj>'hMVubj )}(h h]h }(hjZ'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-'hhhj>'hMVubh)}(hhh]j )}(hcpumaskh]hcpumask}(hjk'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjh'ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjm'modnameN classnameNjL jO )}jR ]jU )}jH pci_irq_get_affinitysbc.pci_irq_get_affinityasbuh1hhj-'hhhj>'hMVubj )}(h h]h }(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-'hhhj>'hMVubji )}(hjl h]h*}(hj'hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hj-'hhhj>'hMVubj )}(hpci_irq_get_affinityh]j )}(hj'h]hpci_irq_get_affinity}(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj'ubah}(h]h ](j j eh"]h$]h&]hhuh1j hj-'hhhj>'hMVubj )}(h(struct pci_dev *dev, int nr)h](j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj'ubj )}(h h]h }(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj'ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj'ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetj'modnameN classnameNjL jO )}jR ]j'c.pci_irq_get_affinityasbuh1hhj'ubj )}(h h]h }(hj(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj'ubji )}(hjl h]h*}(hj(hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hj'ubj )}(hdevh]hdev}(hj(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj'ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj'ubj )}(hint nrh](j )}(hinth]hint}(hj6(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj2(ubj )}(h h]h }(hjD(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj2(ubj )}(hnrh]hnr}(hjR(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj2(ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj'ubeh}(h]h ]h"]h$]h&]hhuh1j hj-'hhhj>'hMVubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj)'hhhj>'hMVubah}(h]j$'ah ](j j eh"]h$]h&]j j )j huh1j hj>'hMVhj&'hhubj )}(hhh]j})}(h&Get a device interrupt vector affinityh]h&Get a device interrupt vector affinity}(hj|(hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMFhjy(hhubah}(h]h ]h"]h$]h&]uh1j hj&'hhhj>'hMVubeh}(h]h ](jF functioneh"]h$]h&]j jF j j(j j(j j j uh1j hhhjn hNhNubj )}(hX**Parameters** ``struct pci_dev *dev`` the PCI device to operate on ``int nr`` device-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode: * MSI-X the index in the MSI-X vector table * MSI the index of the enabled MSI vectors * INTx must be 0 **Return** MSI/MSI-X vector affinity, NULL if **nr** is out of range or if the MSI(-X) vector was allocated without explicit affinity requirements (e.g., by pci_enable_msi(), pci_enable_msix_range(), or pci_alloc_irq_vectors() without the ``PCI_IRQ_AFFINITY`` flag). Return a generic set of CPU IDs representing all possible CPUs available during system boot if the device is in legacy INTx mode.h](j})}(h**Parameters**h]j )}(hj(h]h Parameters}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj(ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMJhj(ubj )}(hhh](j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hj(h]hstruct pci_dev *dev}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj(ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMGhj(ubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj(hMGhj(ubah}(h]h ]h"]h$]h&]uh1j hj(ubeh}(h]h ]h"]h$]h&]uh1j hj(hMGhj(ubj )}(h``int nr`` device-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode: * MSI-X the index in the MSI-X vector table * MSI the index of the enabled MSI vectors * INTx must be 0 h](j )}(h ``int nr``h]j )}(hj(h]hint nr}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj(ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMMhj(ubj )}(hhh](j})}(hfdevice-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode:h]hfdevice-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode:}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMHhj )ubj>)}(hw* MSI-X the index in the MSI-X vector table * MSI the index of the enabled MSI vectors * INTx must be 0 h]j&)}(hhh](j)}(h-MSI-X the index in the MSI-X vector tableh]j})}(hj')h]h-MSI-X the index in the MSI-X vector table}(hj))hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMKhj%)ubah}(h]h ]h"]h$]h&]uh1jhj")ubj)}(h.MSI the index of the enabled MSI vectorsh]j})}(hj?)h]h.MSI the index of the enabled MSI vectors}(hjA)hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMLhj=)ubah}(h]h ]h"]h$]h&]uh1jhj")ubj)}(hINTx must be 0 h]j})}(hINTx must be 0h]hINTx must be 0}(hjY)hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj )hMMhjU)ubah}(h]h ]h"]h$]h&]uh1jhj")ubeh}(h]h ]h"]h$]h&]jjl uh1j%hj6)hMKhj)ubah}(h]h ]h"]h$]h&]uh1j=hj6)hMKhj )ubeh}(h]h ]h"]h$]h&]uh1j hj(ubeh}(h]h ]h"]h$]h&]uh1j hj )hMMhj(ubeh}(h]h ]h"]h$]h&]uh1j hj(ubj})}(h **Return**h]j )}(hj)h]hReturn}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj)ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMOhj(ubj})}(hXMSI/MSI-X vector affinity, NULL if **nr** is out of range or if the MSI(-X) vector was allocated without explicit affinity requirements (e.g., by pci_enable_msi(), pci_enable_msix_range(), or pci_alloc_irq_vectors() without the ``PCI_IRQ_AFFINITY`` flag). Return a generic set of CPU IDs representing all possible CPUs available during system boot if the device is in legacy INTx mode.h](h#MSI/MSI-X vector affinity, NULL if }(hj)hhhNhNubj )}(h**nr**h]hnr}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj)ubh is out of range or if the MSI(-X) vector was allocated without explicit affinity requirements (e.g., by pci_enable_msi(), pci_enable_msix_range(), or pci_alloc_irq_vectors() without the }(hj)hhhNhNubj )}(h``PCI_IRQ_AFFINITY``h]hPCI_IRQ_AFFINITY}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj)ubh flag). Return a generic set of CPU IDs representing all possible CPUs available during system boot if the device is in legacy INTx mode.}(hj)hhhNhNubeh}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMOhj(ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j !pci_free_irq_vectors (C function)c.pci_free_irq_vectorshNtauh1j hjn hhhNhNubj )}(hhh](j )}(h/void pci_free_irq_vectors (struct pci_dev *dev)h]j )}(h.void pci_free_irq_vectors(struct pci_dev *dev)h](j )}(hvoidh]hvoid}(hj)hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj)hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMxubj )}(h h]h }(hj*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj)hhhj*hMxubj )}(hpci_free_irq_vectorsh]j )}(hpci_free_irq_vectorsh]hpci_free_irq_vectors}(hj*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj*ubah}(h]h ](j j eh"]h$]h&]hhuh1j hj)hhhj*hMxubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hj3*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj/*ubj )}(h h]h }(hj@*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj/*ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjQ*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjN*ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetjS*modnameN classnameNjL jO )}jR ]jU )}jH j*sbc.pci_free_irq_vectorsasbuh1hhj/*ubj )}(h h]h }(hjq*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj/*ubji )}(hjl h]h*}(hj*hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hj/*ubj )}(hdevh]hdev}(hj*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj/*ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj+*ubah}(h]h ]h"]h$]h&]hhuh1j hj)hhhj*hMxubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj)hhhj*hMxubah}(h]j)ah ](j j eh"]h$]h&]j j )j huh1j hj*hMxhj)hhubj )}(hhh]j})}(h+Free previously allocated IRQs for a deviceh]h+Free previously allocated IRQs for a device}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMqhj*hhubah}(h]h ]h"]h$]h&]uh1j hj)hhhj*hMxubeh}(h]h ](jF functioneh"]h$]h&]j jF j j*j j*j j j uh1j hhhjn hNhNubj )}(h**Parameters** ``struct pci_dev *dev`` the PCI device to operate on **Description** Undo the interrupt vector allocations and possible device MSI/MSI-X enablement earlier done through pci_alloc_irq_vectors_affinity() or pci_alloc_irq_vectors().h](j})}(h**Parameters**h]j )}(hj*h]h Parameters}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj*ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMuhj*ubj )}(hhh]j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hj*h]hstruct pci_dev *dev}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj*ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMrhj*ubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj +hMrhj +ubah}(h]h ]h"]h$]h&]uh1j hj*ubeh}(h]h ]h"]h$]h&]uh1j hj +hMrhj*ubah}(h]h ]h"]h$]h&]uh1j hj*ubj})}(h**Description**h]j )}(hj2+h]h Description}(hj4+hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj0+ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMthj*ubj})}(hUndo the interrupt vector allocations and possible device MSI/MSI-X enablement earlier done through pci_alloc_irq_vectors_affinity() or pci_alloc_irq_vectors().h]hUndo the interrupt vector allocations and possible device MSI/MSI-X enablement earlier done through pci_alloc_irq_vectors_affinity() or pci_alloc_irq_vectors().}(hjH+hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMthj*ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j "pci_restore_msi_state (C function)c.pci_restore_msi_statehNtauh1j hjn hhhNhNubj )}(hhh](j )}(h0void pci_restore_msi_state (struct pci_dev *dev)h]j )}(h/void pci_restore_msi_state(struct pci_dev *dev)h](j )}(hvoidh]hvoid}(hjw+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjs+hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMubj )}(h h]h }(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjs+hhhj+hMubj )}(hpci_restore_msi_stateh]j )}(hpci_restore_msi_stateh]hpci_restore_msi_state}(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj+ubah}(h]h ](j j eh"]h$]h&]hhuh1j hjs+hhhj+hMubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j )}(hj h]hstruct}(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj+ubj )}(h h]h }(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj+ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj+ubah}(h]h ]h"]h$]h&] refdomainjF reftypejH reftargetj+modnameN classnameNjL jO )}jR ]jU )}jH j+sbc.pci_restore_msi_stateasbuh1hhj+ubj )}(h h]h }(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj+ubji )}(hjl h]h*}(hj,hhhNhNubah}(h]h ]ju ah"]h$]h&]uh1jh hj+ubj )}(hdevh]hdev}(hj ,hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj+ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj+ubah}(h]h ]h"]h$]h&]hhuh1j hjs+hhhj+hMubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjo+hhhj+hMubah}(h]jj+ah ](j j eh"]h$]h&]j j )j huh1j hj+hMhjl+hhubj )}(hhh]j})}(h&Restore cached MSI(-X) state on deviceh]h&Restore cached MSI(-X) state on device}(hj7,hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhj4,hhubah}(h]h ]h"]h$]h&]uh1j hjl+hhhj+hMubeh}(h]h ](jF functioneh"]h$]h&]j jF j jO,j jO,j j j uh1j hhhjn hNhNubj )}(h**Parameters** ``struct pci_dev *dev`` the PCI device to operate on **Description** Write the Linux-cached MSI(-X) state back on device. This is typically useful upon system resume, or after an error-recovery PCI adapter reset.h](j})}(h**Parameters**h]j )}(hjY,h]h Parameters}(hj[,hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjW,ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhjS,ubj )}(hhh]j )}(h5``struct pci_dev *dev`` the PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjx,h]hstruct pci_dev *dev}(hjz,hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjv,ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhjr,ubj )}(hhh]j})}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj,hMhj,ubah}(h]h ]h"]h$]h&]uh1j hjr,ubeh}(h]h ]h"]h$]h&]uh1j hj,hMhjo,ubah}(h]h ]h"]h$]h&]uh1j hjS,ubj})}(h**Description**h]j )}(hj,h]h Description}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj,ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhjS,ubj})}(hWrite the Linux-cached MSI(-X) state back on device. This is typically useful upon system resume, or after an error-recovery PCI adapter reset.h]hWrite the Linux-cached MSI(-X) state back on device. This is typically useful upon system resume, or after an error-recovery PCI adapter reset.}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhjS,ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_msi_enabled (C function)c.pci_msi_enabledhNtauh1j hjn hhhNhNubj )}(hhh](j )}(hint pci_msi_enabled (void)h]j )}(hint pci_msi_enabled(void)h](j )}(hinth]hint}(hj,hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj,hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMubj )}(h h]h }(hj-hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj,hhhj-hMubj )}(hpci_msi_enabledh]j )}(hpci_msi_enabledh]hpci_msi_enabled}(hj-hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-ubah}(h]h ](j j eh"]h$]h&]hhuh1j hj,hhhj-hMubj )}(h(void)h]j )}(hvoidh]j )}(hvoidh]hvoid}(hj5-hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj1-ubah}(h]h ]h"]h$]h&]noemphhhuh1j hj--ubah}(h]h ]h"]h$]h&]hhuh1j hj,hhhj-hMubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj,hhhj-hMubah}(h]j,ah ](j j eh"]h$]h&]j j )j huh1j hj-hMhj,hhubj )}(hhh]j})}(h+Are MSI(-X) interrupts enabled system-wide?h]h+Are MSI(-X) interrupts enabled system-wide?}(hj_-hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhj\-hhubah}(h]h ]h"]h$]h&]uh1j hj,hhhj-hMubeh}(h]h ](jF functioneh"]h$]h&]j jF j jw-j jw-j j j uh1j hhhjn hNhNubj )}(h**Parameters** ``void`` no arguments **Return** true if MSI has not been globally disabled through ACPI FADT, PCI bridge quirks, or the "pci=nomsi" kernel command-line option.h](j})}(h**Parameters**h]j )}(hj-h]h Parameters}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj-ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhj{-ubj )}(hhh]j )}(h``void`` no arguments h](j )}(h``void``h]j )}(hj-h]hvoid}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj-ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhj-ubj )}(hhh]j})}(h no argumentsh]h no arguments}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hj-hMhj-ubah}(h]h ]h"]h$]h&]uh1j hj-ubeh}(h]h ]h"]h$]h&]uh1j hj-hMhj-ubah}(h]h ]h"]h$]h&]uh1j hj{-ubj})}(h **Return**h]j )}(hj-h]hReturn}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj-ubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhj{-ubj})}(htrue if MSI has not been globally disabled through ACPI FADT, PCI bridge quirks, or the "pci=nomsi" kernel command-line option.h]htrue if MSI has not been globally disabled through ACPI FADT, PCI bridge quirks, or the “pci=nomsi” kernel command-line option.}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1j|hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:382: ./drivers/pci/msi/api.chMhj{-ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hjn hhhNhNubeh}(h]!list-of-device-drivers-msi-x-apisah ]h"]#list of device drivers msi(-x) apisah$]h&]uh1jGhjIhhhhhM#ubeh}(h]the-msi-driver-guide-howtoah ]h"]the msi driver guide howtoah$]h&]uh1jGhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jLN 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_handlerj:.error_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}(hhhhhhj jjjj*jj9j-jHj<jWjKjfjZjujijjxjjjjjjjjjjjjjjjjj jjjj)jj8j,jGj;jVjJjejYjtjhjjwjjjjjjjjjjjjjjjjj jjj j(jj7j+jFj:jUjIjdjXjsjgjjvjjjjjjjjjjjjjjjjj jjj j'jj6j*jEj9jTjHjcjWjrjfjjujjjjjjjjjjjjjjjjjjjj j&jj5j)jDj8usubstitution_names}(amphߌaposhasthbrvbarj bsoljcentj*colonj9commajHcommatjWcopyjfcurrenjudarrjdegjdividejdollarjequalsjexcljfrac12jfrac14jfrac18jfrac34j frac38jfrac58j)frac78j8gtjGhalfjVhorbarjehyphenjtiexcljiquestjlaquojlarrjlcubjldquojlowbarjlparjlsqbjlsquoj ltjmicroj(middotj7nbspjFnotjUnumjdohmjsordfjordmjparajpercntjperiodjplusjplusmnjpoundjquestjquotj raquojrarrj'rcubj6rdquojEregjTrparjcrsqbjrrsquojsectjsemijshyjsoljsungjsup1jsup2jsup3jtimesjtradejuarrj&verbarj5yenjDurefnames}refids}nameids}(j.j.jjj4j1jjjjjjjjj3j0jsjpjkjhjjjk jh jd ja j j j j jc j` j .j .u nametypes}(j.jj4jjjjj3jsjkjjk jd j j jc j .uh}(j.jIjjj1jjj7jjjjjjj0jjpj6jhjGjjvjh jja j j jg j j j` j j .jn j j j j jjjjjjj?jDjzjjjjQjVj j j$j$j$'j)'j)j)jj+jo+j,j,u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log]Documentation/PCI/msi-howto.rst(NNNNta decorationNhhub.