diff options
Diffstat (limited to 'static/netbsd/man9/pci_msi.9')
| -rw-r--r-- | static/netbsd/man9/pci_msi.9 | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/static/netbsd/man9/pci_msi.9 b/static/netbsd/man9/pci_msi.9 new file mode 100644 index 00000000..43988809 --- /dev/null +++ b/static/netbsd/man9/pci_msi.9 @@ -0,0 +1,341 @@ +.\" $NetBSD: pci_msi.9,v 1.18 2021/01/12 05:08:50 knakahara Exp $ +.\" +.\" Copyright (c) 2015 Internet Initiative Japan Inc. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd January 12, 2021 +.Dt PCI_MSI 9 +.Os +.Sh NAME +.Nm pci_msi , +.Nm pci_msix , +.Nm pci_msi_count , +.Nm pci_msi_alloc , +.Nm pci_msi_alloc_exact , +.Nm pci_msix_count , +.Nm pci_msix_alloc , +.Nm pci_msix_alloc_exact , +.Nm pci_msix_alloc_map , +.Nm pci_intx_alloc , +.Nm pci_intr_alloc , +.Nm pci_intr_release , +.Nm pci_intr_type +.Nd PCI MSI{,-X} manipulation functions +.Sh SYNOPSIS +.Ft int +.Fn pci_msi_count "pci_chipset_tag_t pc" \ +"pcitag_t tag" +.Ft int +.Fn pci_msi_alloc "const struct pci_attach_args *pa" \ +"pci_intr_handle_t **ihps" "int *count" +.Ft int +.Fn pci_msi_alloc_exact "const struct pci_attach_args *pa" \ +"pci_intr_handle_t **ihps" "int count" +.Ft int +.Fn pci_msix_count "pci_chipset_tag_t pc" \ +"pcitag_t tag" +.Ft int +.Fn pci_msix_alloc "const struct pci_attach_args *pa" \ +"pci_intr_handle_t **ihps" "int *count" +.Ft int +.Fn pci_msix_alloc_exact "const struct pci_attach_args *pa" \ +"pci_intr_handle_t **ihps" "int count" +.Ft int +.Fn pci_msix_alloc_map "const struct pci_attach_args *pa" \ +"pci_intr_handle_t **ihps" "u_int *table_indexes" "int count" +.Ft int +.Fn pci_intx_alloc "const struct pci_attach_args *pa" \ +"pci_intr_handle_t **ihp" +.Ft int +.Fn pci_intr_alloc "const struct pci_attach_args *pa" \ +"pci_intr_handle_t **ihp" "int *counts" \ +"pci_intr_type_t max_type" +.Ft void +.Fn pci_intr_release "pci_chipset_tag_t pc" \ +"pci_intr_handle_t *pih" "int count" +.Ft pci_intr_type_t +.Fn pci_intr_type "pci_chipset_tag_t pc" \ +"pci_intr_handle_t ih" +.Sh DESCRIPTION +The +.Nm +functions exist to allow device drivers to use MSI/MSI-X. +When the system uses MSI/MSI-X, it must define the +.Dv __HAVE_PCI_MSI_MSIX +build option. +.Pp +Each driver has an +.Fn attach +function which has a bus-specific +.Ft attach_args +structure. +Each driver for a PCI device is passed a pointer to an object of type +.Ft struct pci_attach_args +which contains, among other things, information about the location +of the device in the PCI bus topology sufficient to allow interrupts +from the device to be handled. +.Pp +.Fn pci_msi_count +returns the max number of the device's MSI. +If the device can not use MSI, +.Fn pci_msi_count +returns zero. +.Fn pci_msix_count +works in the same manner for MSI-X. +.Pp +If a driver wishes to establish an MSI handler for the device, +it should pass the +.Ft struct pci_attach_args * +and +.Fa count +.Fn pci_msi_alloc +or +.Fn pci_msi_alloc_exact +functions, which return zero on success, and nonzero on failure. +When the functions are successful, they return the pointer to the +allocated handle array in +.Ft pihs +whose size is +.Ft count +or less. +The difference between +.Fn pci_msi_alloc +and +.Fn pci_msi_alloc_exact +is whether +.Fa count +can be decremented or not. +.Fn pci_msi_alloc +can decrement +.Fa count , +and which is similar to +.Fx Ap s +.Fn pci_alloc_msi . +In contrast, +.Fn pci_msi_alloc_exact +can not decrement +.Ft count . +.Pp +If the driver wishes to refer to the MSI source in an attach or +error message, it should use the value returned by +.Fn pci_intr_string +the same as INTx. +The buffer passed to +.Fn pci_intr_string +should be at least +.Dv PCI_INTRSTR_LEN +bytes long. +.Pp +Subsequently, when the driver is prepared to receive MSIs, it +should call +.Fn pci_intr_establish +the same as INTx to actually establish the handler; +when the device interrupts, +.Fa intrhand +will be called with a single argument +.Fa intrarg , +and will run at the interrupt priority level +.Fa ipl . +.Pp +The return value of +.Fn pci_intr_establish +may be saved and passed to +.Fn pci_intr_disestablish +to disable the interrupt handler the same as INTx +when the driver is no longer interested in MSIs from the device. +After that, the driver should also call +.Fn pci_intr_release +to free resources about MSI as well as INTx and MSI-X. +If +.Fa pih +is NULL, +.Fn pci_intr_release +does nothing. +.Pp +If a driver wishes to establish an MSI-X handler for the device, +it is almost the same as MSI. +The only differences is +.Fn pci_msix_alloc_map . +This function can assign separate handlers for each MSI-X table +entry. +I.e., if the driver wants to assign the handlers in the following way: +.Bd -literal + msix_handler0 => MSI-X table index: 4 + msix_handler1 => MSI-X table index: 5 + msix_handler2 => MSI-X table index: 0 +.Ed +the driver should set +.Fa table_indexes +this way: +.Bd -literal + table_indexes[0] = 4; + table_indexes[1] = 5; + table_indexes[2] = 0; +.Ed +.Pp +If the driver wants to fall back to INTx, the driver should use +.Fn pci_intx_alloc +and +.Fn pci_intr_release +instead of +.Fn pci_intr_map +to resolve contradiction of the interrupt handler ownership. +I.e., +.Fn pci_intr_map +does not have the ownership (the function just calculates value), +in contrast, +.Fn pci_msi_alloc +and +.Fn pci_msix_alloc +have (the functions allocate memory for interrupt handlers). +.Pp +.Fn pci_intr_alloc +is wrapper function which select and automatically fallback +allocation functions according to the argument +.Fa counts . +The elements of +.Fa counts +array means each required interrupt count for INTx, MSI, and MSI-X. +The index count of +.Fa counts +must be +.Dv PCI_INTR_TYPE_SIZE . +.Fa max_type +must be +.Dv PCI_INTR_TYPE_MSIX , +.Dv PCI_INTR_TYPE_MSI , +or +.Dv PCI_INTR_TYPE_INTX . +The parameter does not mean array index counts of +.Fa counts . +The parameter means the interrupt type which +.Fn pci_intr_alloc +tries to allocate first. +I.e., if the driver wants to allocate interrupts in the following way: +.Bd -literal + 5 MSI-X + 1 MSI (if MSI-X allocation failed) + INTx (if MSI allocation failed either) +.Ed +the driver should call +.Fn pci_intr_alloc +in the following way: +.Bd -literal + int counts[PCI_INTR_TYPE_SIZE]; + counts[PCI_INTR_TYPE_MSIX] = 5; + counts[PCI_INTR_TYPE_MSI] = 1; + counts[PCI_INTR_TYPE_INTX] = 1; + error = pci_intr_alloc(pa, ihps, counts, + PCI_INTR_TYPE_MSIX); +.Ed +If the driver wants to allocate interrupts in the following way: +.Bd -literal + hardware max number MSI-X + 1 MSI (if MSI-X allocation failed) +.Ed +that is, the driver does not use INTx, the driver should call +.Fn pci_intr_alloc +in the following way: +.Bd -literal + int counts[PCI_INTR_TYPE_SIZE]; + counts[PCI_INTR_TYPE_MSIX] = -1; /* -1 means max */ + counts[PCI_INTR_TYPE_MSI] = 1; + counts[PCI_INTR_TYPE_INTX] = 0; /* 0 means not use */ + error = pci_intr_alloc(pa, ihps, counts, + PCI_INTR_TYPE_MSIX); +.Ed +If the driver wants to allocate interrupts in the following way: +.Bd -literal + 3 MSI + INTx (if MSI allocation failed) +.Ed +that is, the driver does not use MSI-X, the driver should call +.Fn pci_intr_alloc +in the following way: +.Bd -literal + int counts[PCI_INTR_TYPE_SIZE]; + counts[PCI_INTR_TYPE_MSIX] = 0; /* 0 means not use */ + counts[PCI_INTR_TYPE_MSI] = 3; + counts[PCI_INTR_TYPE_INTX] = 1; + error = pci_intr_alloc(pa, ihps, counts, + PCI_INTR_TYPE_MSI); +.Ed +If the driver wants to allocate interrupts in the following way: +.Bd -literal + 1 MSI-X + 1 MSI + INTx (if MSI/MSI-X allocation failed) +.Ed +that is, general usage, the driver should call simply +.Fn pci_intr_alloc +in the following way: +.Bd -literal + error = pci_intr_alloc(pa, ihps, NULL, 0); +.Ed +.Fa max_type +is ignored in this case. +.Fn pci_intr_alloc +returns zero on any allocation function success, and non-zero on +all allocation function failures. +On success, +.Fa counts +is overwritten by a really allocated count. +I.e., if 5 MSI-X is allocated, +.Fa counts +is +.Bd -literal + counts[PCI_INTR_TYPE_MSIX] == 5 + counts[PCI_INTR_TYPE_MSI] == 0 + counts[PCI_INTR_TYPE_INTX] == 0 +.Ed +on return. +.Pp +.Fn pci_intr_type +returns the interrupt type of +.Fa ih . +The return value is +.Dv PCI_INTR_TYPE_MSIX +for MSI-X, +.Dv PCI_INTR_TYPE_MSI +for MSI, and +.Dv PCI_INTR_TYPE_INTX +for others. +.Sh SEE ALSO +.Xr pci_intr 9 +.Sh HISTORY +.Nm +support first appeared in +.Nx 8.0 . +Support is present on +.Em i386 , +.Em amd64 +and +.Em aarch64 +architectures. +.Sh AUTHORS +The +.Nm +interfaces were designed and implemented by +.An Kengo Nakahara +.Aq Mt knakahara@NetBSD.org . |
