Page MenuHomeFreeBSD

D59477.diff
No OneTemporary

D59477.diff

diff --git a/share/man/man9/pci.9 b/share/man/man9/pci.9
--- a/share/man/man9/pci.9
+++ b/share/man/man9/pci.9
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 30, 2026
+.Dd September 16, 2026
.Dt PCI 9
.Os
.Sh NAME
@@ -566,15 +566,21 @@
.Pp
The
.Fn pcie_wait_for_pending_transactions
-function waits for any pending transactions initiated by the
+function polls the Transactions Pending bit in the PCI-express Device Status
+register of
.Fa dev
-device to complete.
-The function checks for pending transactions by polling the transactions
-pending flag in the PCI-express device status register.
+until it is clear or the timeout expires.
+This bit tracks non-posted requests issued by the function, not posted writes
+or the state of its DMA engines.
+It can clear when requests complete, when the Completion Timeout mechanism
+terminates them, or when a Function Level Reset completes.
+A clear bit therefore does not imply successful completion of the requests.
+For Root and Switch Ports, the bit tracks requests issued on the port's own
+behalf, not forwarded requests from downstream functions.
It returns
.Dv true
-once the transaction pending flag is clear.
-If transactions are still pending after
+once the bit is clear.
+If the bit remains set after
.Fa max_delay
milliseconds,
.Fn pcie_wait_for_pending_transactions
@@ -587,7 +593,7 @@
performs a single check;
otherwise,
this function may sleep while polling the transactions pending flag.
-.Nm pcie_wait_for_pending_transactions
+.Fn pcie_wait_for_pending_transactions
returns
.Dv true
if
@@ -607,6 +613,19 @@
.Fn pci_disable_busmaster
function clears this bit.
.Pp
+Both functions read back the Command register to verify the requested state.
+They return zero on success,
+.Er ENXIO
+if a Command-register read returns all ones, or
+.Er EIO
+if the requested state did not take effect.
+An all-ones response does not establish permanent device removal.
+They do not wait for Transactions Pending to clear.
+Drivers should check the return value before relying on the requested state.
+Configuration-access fault handling is provided by the host-controller driver.
+These functions do not catch access exceptions on platforms where an
+inaccessible function causes such an exception.
+.Pp
The
.Fn pci_enable_io
function enables memory or I/O port address decoding for the device
@@ -851,9 +870,9 @@
the PCI-express device control register,
.Dv false
is returned.
-Pending transactions are drained by disabling busmastering and calling
+The function disables bus mastering and calls
.Fn pcie_wait_for_pending_transactions
-before resetting the device.
+to wait for Transactions Pending to clear before resetting the device.
The
.Fa max_delay
argument specifies the maximum timeout to wait for pending transactions as
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -3073,18 +3073,40 @@
PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
}
+static int
+pci_set_busmaster(device_t dev, device_t child, bool enable)
+{
+ uint16_t command;
+
+ /* Host-controller config accessors own fault handling. */
+ command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
+ if (command == 0xffff)
+ return (ENXIO);
+ if (enable)
+ command |= PCIM_CMD_BUSMASTEREN;
+ else
+ command &= ~PCIM_CMD_BUSMASTEREN;
+ PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
+ command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2);
+ if (command == 0xffff)
+ return (ENXIO);
+ if (((command & PCIM_CMD_BUSMASTEREN) != 0) != enable)
+ return (EIO);
+ return (0);
+}
+
int
pci_enable_busmaster_method(device_t dev, device_t child)
{
- pci_set_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
- return (0);
+
+ return (pci_set_busmaster(dev, child, true));
}
int
pci_disable_busmaster_method(device_t dev, device_t child)
{
- pci_clear_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
- return (0);
+
+ return (pci_set_busmaster(dev, child, false));
}
int
@@ -6974,13 +6996,16 @@
}
/*
- * Wait for pending transactions to complete on a PCI-express function.
+ * Wait for Transactions Pending to clear on a PCI-express function.
+ * This tracks the function's outstanding non-posted requests, not posted
+ * writes or the state of its DMA engines. Completion timeout or FLR can
+ * also clear the bit; a clear bit does not imply successful completion.
*
* The maximum delay is specified in milliseconds in max_delay. Note
* that this function may sleep.
*
- * Returns true if the function is idle and false if the timeout is
- * exceeded. If dev is not a PCI-express function, this returns true.
+ * Returns true if Transactions Pending is clear and false if the timeout
+ * is exceeded. If dev is not a PCI-express function, this returns true.
*/
bool
pcie_wait_for_pending_transactions(device_t dev, u_int max_delay)

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 28, 7:17 AM (1 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39793292
Default Alt Text
D59477.diff (4 KB)

Event Timeline