sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget!/translations/zh_CN/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]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget!/translations/pt_BR/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*}hjsbah}(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\}hj#sbah}(h]h ]h"]bsolah$]h&]uh1hhhhK hhhhubh)}(h*.. |cent| unicode:: U+000A2 .. CENT SIGNh]h¢}hj2sbah}(h]h ]h"]centah$]h&]uh1hhhhK hhhhubh)}(h&.. |colon| unicode:: U+0003A .. COLONh]h:}hjAsbah}(h]h ]h"]colonah$]h&]uh1hhhhK hhhhubh)}(h&.. |comma| unicode:: U+0002C .. COMMAh]h,}hjPsbah}(h]h ]h"]commaah$]h&]uh1hhhhKhhhhubh)}(h... |commat| unicode:: U+00040 .. COMMERCIAL ATh]h@}hj_sbah}(h]h ]h"]commatah$]h&]uh1hhhhKhhhhubh)}(h/.. |copy| unicode:: U+000A9 .. COPYRIGHT SIGNh]h©}hjnsbah}(h]h ]h"]copyah$]h&]uh1hhhhKhhhhubh)}(h... |curren| unicode:: U+000A4 .. CURRENCY SIGNh]h¤}hj}sbah}(h]h ]h"]currenah$]h&]uh1hhhhKhhhhubh)}(h0.. |darr| unicode:: U+02193 .. DOWNWARDS ARROWh]h↓}hjsbah}(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⅜}hj"sbah}(h]h ]h"]frac38ah$]h&]uh1hhhhKhhhhubh)}(h=.. |frac58| unicode:: U+0215D .. VULGAR FRACTION FIVE EIGHTHSh]h⅝}hj1sbah}(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>}hjOsbah}(h]h ]h"]gtah$]h&]uh1hhhhKhhhhubh)}(h9.. |half| unicode:: U+000BD .. VULGAR FRACTION ONE HALFh]h½}hj^sbah}(h]h ]h"]halfah$]h&]uh1hhhhK hhhhubh)}(h/.. |horbar| unicode:: U+02015 .. HORIZONTAL BARh]h―}hjmsbah}(h]h ]h"]horbarah$]h&]uh1hhhhK!hhhhubh)}(h'.. |hyphen| unicode:: U+02010 .. HYPHENh]h‐}hj|sbah}(h]h ]h"]hyphenah$]h&]uh1hhhhK"hhhhubh)}(h:.. |iexcl| unicode:: U+000A1 .. INVERTED EXCLAMATION MARKh]h¡}hjsbah}(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µ}hj0sbah}(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 }hjNsbah}(h]h ]h"]nbspah$]h&]uh1hhhhK0hhhhubh)}(h).. |not| unicode:: U+000AC .. NOT SIGNh]h¬}hj]sbah}(h]h ]h"]notah$]h&]uh1hhhhK1hhhhubh)}(h,.. |num| unicode:: U+00023 .. NUMBER SIGNh]h#}hjlsbah}(h]h ]h"]numah$]h&]uh1hhhhK2hhhhubh)}(h).. |ohm| unicode:: U+02126 .. OHM SIGNh]hΩ}hj{sbah}(h]h ]h"]ohmah$]h&]uh1hhhhK3hhhhubh)}(h;.. |ordf| unicode:: U+000AA .. FEMININE ORDINAL INDICATORh]hª}hjsbah}(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→}hj/sbah}(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”}hjMsbah}(h]h ]h"]rdquoah$]h&]uh1hhhhKAhhhhubh)}(h0.. |reg| unicode:: U+000AE .. REGISTERED SIGNh]h®}hj\sbah}(h]h ]h"]regah$]h&]uh1hhhhKBhhhhubh)}(h2.. |rpar| unicode:: U+00029 .. RIGHT PARENTHESISh]h)}hjksbah}(h]h ]h"]rparah$]h&]uh1hhhhKChhhhubh)}(h5.. |rsqb| unicode:: U+0005D .. RIGHT SQUARE BRACKETh]h]}hjzsbah}(h]h ]h"]rsqbah$]h&]uh1hhhhKDhhhhubh)}(h<.. |rsquo| unicode:: U+02019 .. RIGHT SINGLE QUOTATION MARKh]h’}hjsbah}(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™}hjsbah}(h]h ]h"]tradeah$]h&]uh1hhhhKOhhhhubh)}(h... |uarr| unicode:: U+02191 .. UPWARDS ARROWh]h↑}hj.sbah}(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¥}hjLsbah}(h]h ]h"]yenah$]h&]uh1hhhhKRhhhhubhsection)}(hhh](htitle)}(hThe MSI Driver Guide HOWTOh]hThe MSI Driver Guide HOWTO}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hj]hhhhhKubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hAuthorsh]hAuthors}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jzhjwhhhKubh 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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjwubeh}(h]h ]h"]h$]h&]uh1juhhhKhjrhhubjv)}(hhh](j{)}(h Copyrighth]h Copyright}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jzhjhhhKubj)}(h2003, 2008 Intel Corporation h]j)}(h2003, 2008 Intel Corporationh]h2003, 2008 Intel Corporation}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1juhhhK hjrhhubeh}(h]h ]h"]h$]h&]uh1jphj]hhhhhKubj\)}(hhh](ja)}(hAbout this guideh]hAbout this guide}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjhhhhhK 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&]uh1jhhhKhjhhubeh}(h]about-this-guideah ]h"]about this guideah$]h&]uh1j[hj]hhhhhK ubj\)}(hhh](ja)}(hWhat are MSIs?h]hWhat are MSIs?}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjhhhhhKubj)}(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&]uh1jhhhKhjhhubj)}(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.}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubj)}(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.}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK hjhhubeh}(h] what-are-msisah ]h"]what are msis?ah$]h&]uh1j[hj]hhhhhKubj\)}(hhh](ja)}(h Why use MSIs?h]h Why use MSIs?}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjKhhhhhK%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.}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK'hjKhhubj)}(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.}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK*hjKhhubj)}(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.}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK/hjKhhubj)}(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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK:hjKhhubeh}(h] why-use-msisah ]h"] why use msis?ah$]h&]uh1j[hj]hhhhhK%ubj\)}(hhh](ja)}(hHow to use MSIsh]hHow to use MSIs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjhhhhhKFubj)}(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&]uh1jhhhKHhjhhubj\)}(hhh](ja)}(hInclude kernel support for MSIsh]hInclude kernel support for MSIs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjhhhhhKNubj)}(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&]uh1jhhhKPhjhhubeh}(h]include-kernel-support-for-msisah ]h"]include kernel support for msisah$]h&]uh1j[hjhhhhhKNubj\)}(hhh](ja)}(h Using MSIh]h Using MSI}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjhhhhhKWubj)}(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&]uh1jhhhKYhjhhubj)}(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&]uh1jhhhK]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)}(hXTwhich 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 requirement 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]hXVwhich 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 requirement 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKchjhhubj)}(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.}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKihjhhubj)}(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&]uh1jhhhKohjhhubj)}(h9int pci_irq_vector(struct pci_dev *dev, unsigned int nr);h]h9int pci_irq_vector(struct pci_dev *dev, unsigned int nr);}hjIsbah}(h]h ]h"]h$]h&]hhuh1jhhhKrhjhhubj)}(hX0If the driver enables the device using pcim_enable_device(), the driver shouldn't call pci_free_irq_vectors() because pcim_enable_device() activates automatic management for IRQ vectors. Otherwise, the driver should free any allocated IRQ vectors before removing the device using the following function::h]hX1If the driver enables the device using pcim_enable_device(), the driver shouldn’t call pci_free_irq_vectors() because pcim_enable_device() activates automatic management for IRQ vectors. Otherwise, the driver should free any allocated IRQ vectors before removing the device using the following function:}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKthjhhubj)}(h/void pci_free_irq_vectors(struct pci_dev *dev);h]h/void pci_free_irq_vectors(struct pci_dev *dev);}hjesbah}(h]h ]h"]h$]h&]hhuh1jhhhKzhjhhubj)}(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.}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK|hjhhubj)}(h[If a device supports neither MSI-X nor MSI it will fall back to a single legacy IRQ vector.h]h[If a device supports neither MSI-X nor MSI it will fall back to a single legacy IRQ vector.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubj)}(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:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubj)}(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&]uh1jhhhKhjhhubj)}(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&]uh1jhhhKhjhhubj)}(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&]uh1jhhhKhjhhubj)}(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&]uh1j[hjhhhhhKWubj\)}(hhh](ja)}(h Legacy APIsh]h Legacy APIs}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjhhhhhKubj)}(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&]uh1jhhhKhjhhubj)}(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 */}hj&sbah}(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.}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubeh}(h] legacy-apisah ]h"] legacy apisah$]h&]uh1j[hjhhhhhKubj\)}(hhh](ja)}(hConsiderations when using MSIsh]hConsiderations when using MSIs}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjJhhhhhKubj\)}(hhh](ja)}(h Spinlocksh]h Spinlocks}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1j`hj[hhhhhKubj)}(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).}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj[hhubeh}(h] spinlocksah ]h"] spinlocksah$]h&]uh1j[hjJhhhhhKubeh}(h]considerations-when-using-msisah ]h"]considerations when using msisah$]h&]uh1j[hjhhhhhKubj\)}(hhh](ja)}(h4How to tell whether MSI/MSI-X is enabled on a deviceh]h4How to tell whether MSI/MSI-X is enabled on a device}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjhhhhhKubj)}(hUsing 'lspci -v' (as root) may show some devices with "MSI", "Message Signaled Interrupts" or "MSI-X" capabilities. Each of these capabilities has an 'Enable' flag which is followed with either "+" (enabled) or "-" (disabled).h]hUsing ‘lspci -v’ (as root) may show some devices with “MSI”, “Message Signaled 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&]uh1jhhhKhjhhubeh}(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&]uh1j[hjhhhhhKubeh}(h]how-to-use-msisah ]h"]how to use msisah$]h&]uh1j[hj]hhhhhKFubj\)}(hhh](ja)}(h MSI quirksh]h MSI quirks}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j`hjhhhhhKubj)}(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&]uh1jhhhKhjhhubhenumerated_list)}(hhh](h list_item)}(hgloballyh]j)}(hjh]hglobally}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjubah}(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&]uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hon a single device h]j)}(hon a single deviceh]hon a single device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1jhjhhhhhKubj\)}(hhh](ja)}(hDisabling MSIs globallyh]hDisabling MSIs globally}(hj3 hhhNhNubah}(h]h ]h"]h$]h&]uh1j`hj0 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.}(hjA hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj0 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 }(hjO hhhNhNubh reference)}(hlinux-pci@vger.kernel.orgh]hlinux-pci@vger.kernel.org}(hjY hhhNhNubah}(h]h ]h"]h$]h&]refuri mailto:linux-pci@vger.kernel.orguh1jW hjO ubhH including a full ‘lspci -v’ so we can add the quirks to the kernel.}(hjO hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhhhKhj0 hhubeh}(h]disabling-msis-globallyah ]h"]disabling msis globallyah$]h&]uh1j[hjhhhhhKubj\)}(hhh](ja)}(hDisabling MSIs below a bridgeh]hDisabling MSIs below a bridge}(hj~ hhhNhNubah}(h]h ]h"]h$]h&]uh1j`hj{ 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.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj{ 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&]uh1jhhhKhj{ 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&]hhuh1jhhhKhj{ 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&]uh1jhhhKhj{ 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&]uh1jhhhMhj{ hhubj)}(hYAgain, please notify linux-pci@vger.kernel.org of any bridges that need special handling.h](hAgain, please notify }(hj hhhNhNubjX )}(hlinux-pci@vger.kernel.orgh]hlinux-pci@vger.kernel.org}(hj hhhNhNubah}(h]h ]h"]h$]h&]refuri mailto:linux-pci@vger.kernel.orguh1jW hj ubh+ of any bridges that need special handling.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhhhMhj{ hhubeh}(h]disabling-msis-below-a-bridgeah ]h"]disabling msis below a bridgeah$]h&]uh1j[hjhhhhhKubj\)}(hhh](ja)}(h!Disabling MSIs on a single deviceh]h!Disabling MSIs on a single device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j`hj hhhhhM ubj)}(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&]uh1jhhhM hj hhubeh}(h]!disabling-msis-on-a-single-deviceah ]h"]!disabling msis on a single deviceah$]h&]uh1j[hjhhhhhM ubj\)}(hhh](ja)}(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&]uh1j`hj# 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.}(hj4 hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhMhj# 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 }(hjB hhhNhNubhtitle_reference)}(h `/sys/bus/pci/devices/*/msi_bus`h]h/sys/bus/pci/devices/*/msi_bus}(hjL hhhNhNubah}(h]h ]h"]h$]h&]uh1jJ hjB 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.}(hjB hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhhhMhj# 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.}(hjd hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhM hj# hhubeh}(h])finding-why-msis-are-disabled-on-a-deviceah ]h"])finding why msis are disabled on a deviceah$]h&]uh1j[hjhhhhhMubeh}(h] msi-quirksah ]h"] msi quirksah$]h&]uh1j[hj]hhhhhKubj\)}(hhh](ja)}(h#List of device drivers MSI(-X) APIsh]h#List of device drivers MSI(-X) APIs}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j`hj 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 hhhNhNubjK )}(h`drivers/pci/msi/api.c`h]hdrivers/pci/msi/api.c}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jJ hj ubh'. The following functions are exported:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhhhM(hj hhubhindex)}(hhh]h}(h]h ]h"]h$]h&]entries](singlepci_enable_msi (C function)c.pci_enable_msihNtauh1j hj 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:385: ./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 }(hj4 hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjE hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjB ubah}(h]h ]h"]h$]h&] refdomaincreftype identifier reftargetjG modnameN classnameN c:parent_keysphinx.domains.c LookupKey)}data]ja ASTIdentifier)}j\ j sbc.pci_enable_msiasbuh1hhj ubj )}(h h]h }(hjn hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj ubhdesc_sig_punctuation)}(h*h]h*}(hj~ hhhNhNubah}(h]h ]pah"]h$]h&]uh1j| 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 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj hhubah}(h]h ]h"]h$]h&]uh1j hj hhhj hKubeh}(h]h ](jZ functioneh"]h$]h&]domainjZ objtypej desctypej noindex noindexentrynocontentsentryuh1j hhhj 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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:385: ./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&]uh1jhj) 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 )}(hjQ h]h Description}(hjS hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjO ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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 }(hjg hhhNhNubj )}(h **dev->irq**h]hdev->irq}(hjo hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjg ubh6. The driver must invoke pci_disable_msi() on cleanup.}(hjg hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj ubj)}(h**NOTE**h]j )}(hj h]hNOTE}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj ubj)}(h0 on success, errno otherwiseh]h0 on success, errno otherwise}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_disable_msi (C function)c.pci_disable_msihNtauh1j hj 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:385: ./drivers/pci/msi/api.chK(ubj )}(h h]h }(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj hhhj hK(ubj )}(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 hK(ubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j$ )}(hj' h]hstruct}(hj3 hhhNhNubah}(h]h ]j0 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&] refdomainjZ reftypej\ reftargetjS modnameN classnameNj` jc )}jf ]ji )}j\ j sbc.pci_disable_msiasbuh1hhj/ ubj )}(h h]h }(hjq hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj/ ubj} )}(hj h]h*}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| 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 hK(ubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj hhhj hK(ubah}(h]j ah ](j j eh"]h$]h&]j j )j huh1j hj hK(hj hhubj )}(hhh]j)}(h$Disable MSI interrupt mode on deviceh]h$Disable MSI interrupt mode on device}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chK(hj hhubah}(h]h ]h"]h$]h&]uh1j hj hhhj hK(ubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j j j j j j j uh1j hhhj 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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:385: ./drivers/pci/msi/api.chK)hj ubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj 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 )}(hj2h]h Description}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj0ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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 (}(hjHhhhNhNubj )}(h **dev->irq**h]hdev->irq}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjHubh]) is restored to its default pin-assertion IRQ. This is the cleanup pair of pci_enable_msi().}(hjHhhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chK*hj ubj)}(h**NOTE**h]j )}(hjkh]hNOTE}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjiubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chK/hj 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.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chK0hj ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_msix_vec_count (C function)c.pci_msix_vec_counthNtauh1j hj 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:385: ./drivers/pci/msi/api.chK?ubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhjhK?ubj )}(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 hjhhhjhK?ubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j$ )}(hj' h]hstruct}(hjhhhNhNubah}(h]h ]j0 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 hjubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetj modnameN classnameNj` jc )}jf ]ji )}j\ jsbc.pci_msix_vec_countasbuh1hhjubj )}(h h]h }(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj} )}(hj h]h*}(hj9hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hjubj )}(hdevh]hdev}(hjFhhhNhNubah}(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)}(h/Get number of MSI-X interrupt vectors on deviceh]h/Get number of MSI-X interrupt vectors on device}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chK?hjmhhubah}(h]h ]h"]h$]h&]uh1j hjhhhjhK?ubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j jj jj j j uh1j hhhj 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 )}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKChjubj )}(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:385: ./drivers/pci/msi/api.chK@hjubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhK@hjubah}(h]h ]h"]h$]h&]uh1j* hjubeh}(h]h ]h"]h$]h&]uh1j hjhK@hjubah}(h]h ]h"]h$]h&]uh1j hjubj)}(h **Return**h]j )}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKBhjubj)}(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKBhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j "pci_enable_msix_range (C function)c.pci_enable_msix_rangehNtauh1j hj 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}(hj1hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKSubj )}(h h]h }(hj@hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-hhhj?hKSubj )}(hpci_enable_msix_rangeh]j )}(hpci_enable_msix_rangeh]hpci_enable_msix_range}(hjRhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjNubah}(h]h ](j j eh"]h$]h&]hhuh1j hj-hhhj?hKSubj )}(hI(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec)h](j )}(hstruct pci_dev *devh](j$ )}(hj' h]hstruct}(hjnhhhNhNubah}(h]h ]j0 ah"]h$]h&]uh1j# hjjubj )}(h h]h }(hj{hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjjubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetjmodnameN classnameNj` jc )}jf ]ji )}j\ jTsbc.pci_enable_msix_rangeasbuh1hhjjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjjubj} )}(hj h]h*}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hjjubj )}(hdevh]hdev}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjfubj )}(hstruct msix_entry *entriesh](j$ )}(hj' h]hstruct}(hjhhhNhNubah}(h]h ]j0 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&] refdomainjZ reftypej\ reftargetjmodnameN classnameNj` jc )}jf ]jc.pci_enable_msix_rangeasbuh1hhjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj} )}(hj h]h*}(hj*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hjubj )}(hentriesh]hentries}(hj7hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjfubj )}(h int minvech](j )}(hinth]hint}(hjPhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjLubj )}(h h]h }(hj^hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjLubj )}(hminvech]hminvec}(hjlhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjLubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjfubj )}(h int maxvech](j )}(hinth]hint}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj )}(hmaxvech]hmaxvec}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjfubeh}(h]h ]h"]h$]h&]hhuh1j hj-hhhj?hKSubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj)hhhj?hKSubah}(h]j$ah ](j j eh"]h$]h&]j j )j huh1j hj?hKShj&hhubj )}(hhh]j)}(h%Enable MSI-X interrupt mode on deviceh]h%Enable MSI-X interrupt mode on device}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKShjhhubah}(h]h ]h"]h$]h&]uh1j hj&hhhj?hKSubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j jj jj j j uh1j hhhj 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKWhjubj )}(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}(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:385: ./drivers/pci/msi/api.chKThjubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj!hKThj"ubah}(h]h ]h"]h$]h&]uh1j* hjubeh}(h]h ]h"]h$]h&]uh1j hj!hKThjubj )}(h\``struct msix_entry *entries`` input/output parameter, array of MSI-X configuration entries h](j )}(h``struct msix_entry *entries``h]j )}(hjEh]hstruct msix_entry *entries}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjCubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKUhj?ubj+ )}(hhh]j)}(h= 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 )}(hjMh]h Parameters}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjKubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjGubj )}(hhh](j )}(h1``struct pci_dev *dev`` PCI device to operate on h](j )}(h``struct pci_dev *dev``h]j )}(hjlh]hstruct pci_dev *dev}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjjubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjfubj+ )}(hhh]j)}(hPCI device to operate onh]hPCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1j* hjfubeh}(h]h ]h"]h$]h&]uh1j hjhKhjcubj )}(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:385: ./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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjubah}(h]h ]h"]h$]h&]uh1j* hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjcubj )}(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:385: ./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}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1j* hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjcubeh}(h]h ]h"]h$]h&]uh1j hjGubj)}(h **Return**h]j )}(hj,h]hReturn}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj*ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjGubj)}(hA struct msi_maph]hA struct msi_map}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjGubj)}(h**Description**h]j )}(hjSh]h Description}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjQubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjGubh 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).}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjkubj)}(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.}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjkubeh}(h]h ]h"]h$]h&]uh1jihj}hKhjGubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_msix_free_irq (C function)c.pci_msix_free_irqhNtauh1j hj 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:385: ./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 ]j0 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 hj ubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetjmodnameN classnameNj` jc )}jf ]ji )}j\ jsbc.pci_msix_free_irqasbuh1hhjubj )}(h h]h }(hj.hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj} )}(hj h]h*}(hj<hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hjubj )}(hdevh]hdev}(hjIhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(hstruct msi_map maph](j$ )}(hj' h]hstruct}(hjbhhhNhNubah}(h]h ]j0 ah"]h$]h&]uh1j# hj^ubj )}(h h]h }(hjohhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj^ubh)}(hhh]j )}(hmsi_maph]hmsi_map}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj}ubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetjmodnameN classnameNj` jc )}jf ]j*c.pci_msix_free_irqasbuh1hhj^ubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj^ubj )}(hmaph]hmap}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj^ubeh}(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]jah ](j j eh"]h$]h&]j j )j huh1j hjhKhjhhubj )}(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjhhubah}(h]h ]h"]h$]h&]uh1j hjhhhjhKubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j jj jj j j uh1j hhhj 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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:385: ./drivers/pci/msi/api.chKhjubj+ )}(hhh]j)}(hThe PCI device to operate onh]hThe PCI device to operate on}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj,hKhj-ubah}(h]h ]h"]h$]h&]uh1j* hjubeh}(h]h ]h"]h$]h&]uh1j hj,hKhjubj )}(hI``struct msi_map map`` A struct msi_map describing the interrupt to free h](j )}(h``struct msi_map map``h]j )}(hjPh]hstruct msi_map map}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjNubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjJubj+ )}(hhh]j)}(h1A struct msi_map describing the interrupt to freeh]h1A struct msi_map describing the interrupt to free}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1jhjehKhjfubah}(h]h ]h"]h$]h&]uh1j* hjJubeh}(h]h ]h"]h$]h&]uh1j hjehKhjubeh}(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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:385: ./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&]uh1jhjhKhjubah}(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 )}(hj h]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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 (}(hj"hhhNhNubj )}(h **dev->irq**h]hdev->irq}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj"ubhd) is restored to its default pin assertion IRQ. This is the cleanup pair of pci_enable_msix_range().}(hj"hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjubj)}(h**NOTE**h]j )}(hjEh]hNOTE}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjCubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j "pci_alloc_irq_vectors (C function)c.pci_alloc_irq_vectorshNtauh1j hj 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}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjhhhjhKubj )}(hpci_alloc_irq_vectorsh]j )}(hpci_alloc_irq_vectorsh]hpci_alloc_irq_vectors}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubah}(h]h ](j j eh"]h$]h&]hhuh1j hjhhhjhKubj )}(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 ]j0 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&] refdomainjZ reftypej\ reftargetjmodnameN classnameNj` jc )}jf ]ji )}j\ jsbc.pci_alloc_irq_vectorsasbuh1hhjubj )}(h h]h }(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubj} )}(hj h]h*}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hjubj )}(hdevh]hdev}(hj hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(hunsigned int min_vecsh](j )}(hunsignedh]hunsigned}(hj9hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj5ubj )}(h h]h }(hjGhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj5ubj )}(hinth]hint}(hjUhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj5ubj )}(h h]h }(hjchhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj5ubj )}(hmin_vecsh]hmin_vecs}(hjqhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj5ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hjubj )}(hunsigned int max_vecsh](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 )}(hmax_vecsh]hmax_vecs}(hjhhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjubeh}(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 hjhhhjhKubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjhhhjhKubah}(h]j}ah ](j j eh"]h$]h&]j j )j huh1j hjhKhjhhubj )}(hhh]j)}(h*Allocate multiple device interrupt vectorsh]h*Allocate multiple device interrupt vectors}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj:hhubah}(h]h ]h"]h$]h&]uh1j hjhhhjhKubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j jUj jUj j j uh1j hhhj 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: **Description** * ``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 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 )}(hj_h]h Parameters}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1j hj]ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjYubj )}(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}(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:385: ./drivers/pci/msi/api.chKhjxubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1j* hjxubeh}(h]h ]h"]h$]h&]uh1j hjhKhjuubj )}(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:385: ./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&]uh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1j* hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjuubj )}(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:385: ./drivers/pci/msi/api.chKhjubj+ )}(hhh]j)}(h!maximum desired number of vectorsh]h!maximum desired number of vectors}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhKhjubah}(h]h ]h"]h$]h&]uh1j* hjubeh}(h]h ]h"]h$]h&]uh1j hjhKhjuubj )}(h'``unsigned int flags`` One or more of: 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:385: ./drivers/pci/msi/api.chKhj#ubj+ )}(hhh]j)}(hOne or more of:h]hOne or more of:}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj>hKhj?ubah}(h]h ]h"]h$]h&]uh1j* hj#ubeh}(h]h ]h"]h$]h&]uh1j hj>hKhjuubeh}(h]h ]h"]h$]h&]uh1j hjYubj)}(h**Description**h]j )}(hjdh]h Description}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjbubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjYubjj)}(hX8* ``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]h bullet_list)}(hhh](j)}(h;``PCI_IRQ_MSIX`` Allow trying MSI-X vector allocationsh]j)}(hjh](j )}(h``PCI_IRQ_MSIX``h]h PCI_IRQ_MSIX}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh+ Allow trying MSI-X vector allocations}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(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}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh* Allow trying MSI vector allocations}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(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 hjubh3 Allow trying INTx interrupts, if and only if }(hjhhhNhNubj )}(h **min_vecs**h]hmin_vecs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j hjubh == 1}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(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}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhJ Auto-manage IRQs affinity by spreading the vectors around available CPUs}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]bulletj uh1j~hjhKhjzubah}(h]h ]h"]h$]h&]uh1jihjhKhjYubj)}(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}(hjE 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjYubj)}(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjYubj)}(h **Return**h]j )}(hjo h]hReturn}(hjq hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjm ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjYubj)}(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 }(hj hhhNhNubj )}(h **max_vecs**h]hmax_vecs}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh), -ENOSPC if less than }(hj hhhNhNubj )}(h **min_vecs**h]hmin_vecs}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh9 interrupt vectors are available, other errnos otherwise.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjYubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j +pci_alloc_irq_vectors_affinity (C function) c.pci_alloc_irq_vectors_affinityhNtauh1j hj 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:385: ./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 ]j0 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}(hj3!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj0!ubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetj5!modnameN classnameNj` jc )}jf ]ji )}j\ j sb c.pci_alloc_irq_vectors_affinityasbuh1hhj!ubj )}(h h]h }(hjS!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!ubj} )}(hj h]h*}(hja!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| 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 min_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 )}(hmin_vecsh]hmin_vecs}(hj!hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj!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 }(hj7"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%"ubj )}(hinth]hint}(hjE"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%"ubj )}(h h]h }(hjS"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%"ubj )}(hflagsh]hflags}(hja"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}(hjz"hhhNhNubah}(h]h ]j0 ah"]h$]h&]uh1j# hjv"ubj )}(h h]h }(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjv"ubh)}(hhh]j )}(h irq_affinityh]h irq_affinity}(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj"ubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetj"modnameN classnameNj` jc )}jf ]jO! c.pci_alloc_irq_vectors_affinityasbuh1hhjv"ubj )}(h h]h }(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjv"ubj} )}(hj h]h*}(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hjv"ubj )}(haffdh]haffd}(hj"hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjv"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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj"hhubah}(h]h ]h"]h$]h&]uh1j hj hhhj hKubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j j#j j#j j j uh1j hhhj 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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:385: ./drivers/pci/msi/api.chKhj6#ubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjU#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjQ#hKhjR#ubah}(h]h ]h"]h$]h&]uh1j* hj6#ubeh}(h]h ]h"]h$]h&]uh1j hjQ#hKhj3#ubj )}(hL``unsigned int min_vecs`` minimum required number of vectors (must be >= 1) h](j )}(h``unsigned int min_vecs``h]j )}(hju#h]hunsigned int min_vecs}(hjw#hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjs#ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhjo#ubj+ )}(hhh]j)}(h1minimum required number of vectors (must be >= 1)h]h1minimum required number of vectors (must be >= 1)}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#hKhj#ubah}(h]h ]h"]h$]h&]uh1j* hjo#ubeh}(h]h ]h"]h$]h&]uh1j hj#hKhj3#ubj )}(h<``unsigned int max_vecs`` maximum desired number of vectors h](j )}(h``unsigned int max_vecs``h]j )}(hj#h]hunsigned int max_vecs}(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:385: ./drivers/pci/msi/api.chKhj#ubj+ )}(hhh]j)}(h!maximum desired number of vectorsh]h!maximum desired number of vectors}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj#hKhj#ubah}(h]h ]h"]h$]h&]uh1j* hj#ubeh}(h]h ]h"]h$]h&]uh1j hj#hKhj3#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:385: ./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&]uh1jhj#hKhj#ubah}(h]h ]h"]h$]h&]uh1j* hj#ubeh}(h]h ]h"]h$]h&]uh1j hj#hKhj3#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:385: ./drivers/pci/msi/api.chKhj$ubj+ )}(hhh]j)}(h(affinity requirements (can be ``NULL``).h](haffinity requirements (can be }(hj9$hhhNhNubj )}(h``NULL``h]hNULL}(hjA$hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj9$ubh).}(hj9$hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhj5$hKhj6$ubah}(h]h ]h"]h$]h&]uh1j* hj$ubeh}(h]h ]h"]h$]h&]uh1j hj5$hKhj3#ubeh}(h]h ]h"]h$]h&]uh1j hj#ubj)}(h**Description**h]j )}(hjm$h]h Description}(hjo$hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjk$ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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 }(hj$hhhNhNubj )}(h**affd**h]haffd}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj$ubh* parameter. Check that function docs, and }(hj$hhhNhNubh)}(h,:c:type:`struct irq_affinity `h]j )}(hj$h]hstruct irq_affinity}(hj$hhhNhNubah}(h]h ](xrefjZ c-typeeh"]h$]h&]uh1j hj$ubah}(h]h ]h"]h$]h&]refdoc PCI/msi-howto refdomainjZ reftypetype refexplicitrefwarnj` jc )}jf ]sb reftarget irq_affinityuh1hhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj$ubh, for more details.}(hj$hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhj$hKhj#ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_irq_vector (C function)c.pci_irq_vectorhNtauh1j hj 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:385: ./drivers/pci/msi/api.chM,ubj )}(h h]h }(hj$hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj$hhhj$hM,ubj )}(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$hM,ubj )}(h&(struct pci_dev *dev, unsigned int nr)h](j )}(hstruct pci_dev *devh](j$ )}(hj' h]hstruct}(hj*%hhhNhNubah}(h]h ]j0 ah"]h$]h&]uh1j# hj&%ubj )}(h h]h }(hj7%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj&%ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjH%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjE%ubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetjJ%modnameN classnameNj` jc )}jf ]ji )}j\ j%sbc.pci_irq_vectorasbuh1hhj&%ubj )}(h h]h }(hjh%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj&%ubj} )}(hj h]h*}(hjv%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hj&%ubj )}(hdevh]hdev}(hj%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj&%ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj"%ubj )}(hunsigned int nrh](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 )}(hnrh]hnr}(hj%hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj%ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj"%ubeh}(h]h ]h"]h$]h&]hhuh1j hj$hhhj$hM,ubeh}(h]h ]h"]h$]h&]hhj uh1j j j hj$hhhj$hM,ubah}(h]j$ah ](j j eh"]h$]h&]j j )j huh1j hj$hM,hj$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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM,hj%hhubah}(h]h ]h"]h$]h&]uh1j hj$hhhj$hM,ubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j j&j j&j j j uh1j hhhj 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: **Description** * 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM0hj&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}(hjA&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:385: ./drivers/pci/msi/api.chM-hj9&ubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjX&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjT&hM-hjU&ubah}(h]h ]h"]h$]h&]uh1j* hj9&ubeh}(h]h ]h"]h$]h&]uh1j hjT&hM-hj6&ubj )}(h{``unsigned int nr`` device-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode: h](j )}(h``unsigned int nr``h]j )}(hjx&h]hunsigned int nr}(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:385: ./drivers/pci/msi/api.chM/hjr&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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM.hj&ubah}(h]h ]h"]h$]h&]uh1j* hjr&ubeh}(h]h ]h"]h$]h&]uh1j hj&hM/hj6&ubeh}(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM1hj&ubjj)}(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM0hj&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}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM1hj&ubah}(h]h ]h"]h$]h&]uh1jhj&ubj)}(hINTx must be 0 h]j)}(hINTx must be 0h]hINTx must be 0}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM2hj'ubah}(h]h ]h"]h$]h&]uh1jhj&ubeh}(h]h ]h"]h$]h&]j6 j uh1j~hj&hM0hj&ubah}(h]h ]h"]h$]h&]uh1jihj&hM0hj&ubj)}(h **Return**h]j )}(hj('h]hReturn}(hj*'hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj&'ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM4hj&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}(hjF'hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj>'ubh is out of range}(hj>'hhhNhNubeh}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chM5hj&ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j !pci_irq_get_affinity (C function)c.pci_irq_get_affinityhNtauh1j hj 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$ )}(hjh]hconst}(hj'hhhNhNubah}(h]h ]j0 ah"]h$]h&]uh1j# hj{'hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMDubj )}(h h]h }(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj{'hhhj'hMDubj$ )}(hj' h]hstruct}(hj'hhhNhNubah}(h]h ]j0 ah"]h$]h&]uh1j# hj{'hhhj'hMDubj )}(h h]h }(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj{'hhhj'hMDubh)}(hhh]j )}(hcpumaskh]hcpumask}(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj'ubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetj'modnameN classnameNj` jc )}jf ]ji )}j\ pci_irq_get_affinitysbc.pci_irq_get_affinityasbuh1hhj{'hhhj'hMDubj )}(h h]h }(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj{'hhhj'hMDubj} )}(hj h]h*}(hj'hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hj{'hhhj'hMDubj )}(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'hMDubj )}(h(struct pci_dev *dev, int nr)h](j )}(hstruct pci_dev *devh](j$ )}(hj' h]hstruct}(hj(hhhNhNubah}(h]h ]j0 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}(hj2(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj/(ubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetj4(modnameN classnameNj` jc )}jf ]j'c.pci_irq_get_affinityasbuh1hhj(ubj )}(h h]h }(hjP(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj(ubj} )}(hj h]h*}(hj^(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| hj(ubj )}(hdevh]hdev}(hjk(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj(ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj (ubj )}(hint nrh](j )}(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 )}(hnrh]hnr}(hj(hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj(ubeh}(h]h ]h"]h$]h&]noemphhhuh1j hj (ubeh}(h]h ]h"]h$]h&]hhuh1j hj{'hhhj'hMDubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjw'hhhj'hMDubah}(h]jr'ah ](j j eh"]h$]h&]j j )j huh1j hj'hMDhjt'hhubj )}(hhh]j)}(h&Get a device interrupt vector affinityh]h&Get a device interrupt vector affinity}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMDhj(hhubah}(h]h ]h"]h$]h&]uh1j hjt'hhhj'hMDubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j j(j j(j j j uh1j hhhj 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: **Description** * 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMHhj(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:385: ./drivers/pci/msi/api.chMEhj)ubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj$)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj )hMEhj!)ubah}(h]h ]h"]h$]h&]uh1j* hj)ubeh}(h]h ]h"]h$]h&]uh1j hj )hMEhj)ubj )}(hr``int nr`` device-relative interrupt vector index (0-based); has different meanings, depending on interrupt mode: h](j )}(h ``int nr``h]j )}(hjD)h]hint nr}(hjF)hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjB)ubah}(h]h ]h"]h$]h&]uh1j hT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMGhj>)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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMFhjZ)ubah}(h]h ]h"]h$]h&]uh1j* hj>)ubeh}(h]h ]h"]h$]h&]uh1j hjY)hMGhj)ubeh}(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMIhj(ubjj)}(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMHhj)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}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMIhj)ubah}(h]h ]h"]h$]h&]uh1jhj)ubj)}(hINTx must be 0 h]j)}(hINTx must be 0h]hINTx must be 0}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMJhj)ubah}(h]h ]h"]h$]h&]uh1jhj)ubeh}(h]h ]h"]h$]h&]j6 j uh1j~hj)hMHhj)ubah}(h]h ]h"]h$]h&]uh1jihj)hMHhj(ubj)}(h **Return**h]j )}(hj)h]hReturn}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj)ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMLhj(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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMMhj(ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j !pci_free_irq_vectors (C function)c.pci_free_irq_vectorshNtauh1j hj 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 hjY*hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMoubj )}(h h]h }(hjl*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjY*hhhjk*hMoubj )}(hpci_free_irq_vectorsh]j )}(hpci_free_irq_vectorsh]hpci_free_irq_vectors}(hj~*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjz*ubah}(h]h ](j j eh"]h$]h&]hhuh1j hjY*hhhjk*hMoubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j$ )}(hj' h]hstruct}(hj*hhhNhNubah}(h]h ]j0 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&] refdomainjZ reftypej\ reftargetj*modnameN classnameNj` jc )}jf ]ji )}j\ j*sbc.pci_free_irq_vectorsasbuh1hhj*ubj )}(h h]h }(hj*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj*ubj} )}(hj h]h*}(hj*hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| 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 hjY*hhhjk*hMoubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjU*hhhjk*hMoubah}(h]jP*ah ](j j eh"]h$]h&]j j )j huh1j hjk*hMohjR*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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMohj+hhubah}(h]h ]h"]h$]h&]uh1j hjR*hhhjk*hMoubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j j5+j j5+j j j uh1j hhhj hNhNubj )}(hX**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(). WARNING: Do not call this function if the device has been enabled with pcim_enable_device(). In that case, IRQ vectors are automatically managed via pcim_msi_release() and calling pci_free_irq_vectors() can lead to double-free issues.h](j)}(h**Parameters**h]j )}(hj?+h]h Parameters}(hjA+hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj=+ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMshj9+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:385: ./drivers/pci/msi/api.chMphjX+ubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hjw+hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjs+hMphjt+ubah}(h]h ]h"]h$]h&]uh1j* hjX+ubeh}(h]h ]h"]h$]h&]uh1j hjs+hMphjU+ubah}(h]h ]h"]h$]h&]uh1j hj9+ubj)}(h**Description**h]j )}(hj+h]h Description}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj+ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMrhj9+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().}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMqhj9+ubj)}(hWARNING: Do not call this function if the device has been enabled with pcim_enable_device(). In that case, IRQ vectors are automatically managed via pcim_msi_release() and calling pci_free_irq_vectors() can lead to double-free issues.h]hWARNING: Do not call this function if the device has been enabled with pcim_enable_device(). In that case, IRQ vectors are automatically managed via pcim_msi_release() and calling pci_free_irq_vectors() can lead to double-free issues.}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMuhj9+ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j "pci_restore_msi_state (C function)c.pci_restore_msi_statehNtauh1j hj 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}(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj+hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMubj )}(h h]h }(hj+hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj+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 hj+hhhj+hMubj )}(h(struct pci_dev *dev)h]j )}(hstruct pci_dev *devh](j$ )}(hj' h]hstruct}(hj*,hhhNhNubah}(h]h ]j0 ah"]h$]h&]uh1j# hj&,ubj )}(h h]h }(hj7,hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj&,ubh)}(hhh]j )}(hpci_devh]hpci_dev}(hjH,hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjE,ubah}(h]h ]h"]h$]h&] refdomainjZ reftypej\ reftargetjJ,modnameN classnameNj` jc )}jf ]ji )}j\ j,sbc.pci_restore_msi_stateasbuh1hhj&,ubj )}(h h]h }(hjh,hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj&,ubj} )}(hj h]h*}(hjv,hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j| 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+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&Restore cached MSI(-X) state on deviceh]h&Restore cached MSI(-X) state on device}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMhj,hhubah}(h]h ]h"]h$]h&]uh1j hj+hhhj+hMubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j j,j j,j j j uh1j hhhj 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 )}(hj,h]h Parameters}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj,ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMhj,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:385: ./drivers/pci/msi/api.chMhj,ubj+ )}(hhh]j)}(hthe PCI device to operate onh]hthe PCI device to operate on}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj-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**Description**h]j )}(hj)-h]h Description}(hj+-hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj'-ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMhj,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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMhj,ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubj )}(hhh]h}(h]h ]h"]h$]h&]entries](j pci_msi_enabled (C function)c.pci_msi_enabledhNtauh1j hj hhhNhNubj )}(hhh](j )}(hbool pci_msi_enabled (void)h]j )}(hbool pci_msi_enabled(void)h](j )}(hjh]hbool}(hjn-hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjj-hhhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMubj )}(h h]h }(hj|-hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hjj-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 hjj-hhhj{-hMubj )}(h(void)h]j )}(hvoidh]j )}(hvoidh]hvoid}(hj-hhhNhNubah}(h]h ]j ah"]h$]h&]uh1j hj-ubah}(h]h ]h"]h$]h&]noemphhhuh1j hj-ubah}(h]h ]h"]h$]h&]hhuh1j hjj-hhhj{-hMubeh}(h]h ]h"]h$]h&]hhj uh1j j j hjf-hhhj{-hMubah}(h]ja-ah ](j j eh"]h$]h&]j j )j huh1j hj{-hMhjc-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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMhj-hhubah}(h]h ]h"]h$]h&]uh1j hjc-hhhj{-hMubeh}(h]h ](jZ functioneh"]h$]h&]j jZ j j-j j-j j j uh1j hhhj 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&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./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:385: ./drivers/pci/msi/api.chKhj.ubj+ )}(hhh]j)}(h no argumentsh]h no arguments}(hj..hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj*.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 **Return**h]j )}(hjP.h]hReturn}(hjR.hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjN.ubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chKhj-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.}(hjf.hhhNhNubah}(h]h ]h"]h$]h&]uh1jhT/var/lib/git/docbuild/linux/Documentation/PCI/msi-howto:385: ./drivers/pci/msi/api.chMhj-ubeh}(h]h ] kernelindentah"]h$]h&]uh1j hj hhhNhNubeh}(h]!list-of-device-drivers-msi-x-apisah ]h"]#list of device drivers msi(-x) apisah$]h&]uh1j[hj]hhhhhM&ubeh}(h]the-msi-driver-guide-howtoah ]h"]the msi driver guide howtoah$]h&]uh1j[hhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(j`N 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_sourcehnj _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}(hhjhjjj jj/j#j>j2jMjAj\jPjkj_jzjnjj}jjjjjjjjjjjjjjjjjjjjj.j"j=j1jLj@j[jOjjj^jyjmjj|jjjjjjjjjjjjjjjjjjjjj-j!j<j0jKj?jZjNjij]jxjljj{jjjjjjjjjjjjjjjjjjjjj,j j;j/jJj>jYjMjhj\jwjkjjzjjjjjjjjjjjjjjjjj jjjj+jj:j.jIj=jXjLusubstitution_names}(amphaposjastjbrvbarj bsolj/centj>colonjMcommaj\commatjkcopyjzcurrenjdarrjdegjdividejdollarjequalsjexcljfrac12jfrac14jfrac18jfrac34jfrac38j.frac58j=frac78jLgtj[halfjjhorbarjyhyphenjiexcljiquestjlaquojlarrjlcubjldquojlowbarjlparjlsqbjlsquojltj-microj<middotjKnbspjZnotjinumjxohmjordfjordmjparajpercntjperiodjplusjplusmnjpoundjquestjquotjraquoj,rarrj;rcubjJrdquojYregjhrparjwrsqbjrsquojsectjsemijshyjsoljsungjsup1jsup2jsup3j timesjtradej+uarrj:verbarjIyenjXurefnames}refids}nameids}(j.j.jjjHjEjjjjjjjjjGjDjjjj|jjj j| jx ju j j j j jw jt j.j~.u nametypes}(j.jjHjjjjjGjjjj jx j j jw j.uh}(j.j]jjjEjjjKjjjjjjjDjjjJj|j[jjj| jju j0 j j{ j j jt j# j~.j j j j j jjj$j)jjjSjXjjjjj}jj j j$j$jr'jw'jP*jU*j+j+ja-jf-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.