summaryrefslogtreecommitdiff
path: root/static/netbsd/man9/pci_msi.9
diff options
context:
space:
mode:
Diffstat (limited to 'static/netbsd/man9/pci_msi.9')
-rw-r--r--static/netbsd/man9/pci_msi.9341
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 .