Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173628582
D59477.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D59477.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D59477: pci: Verify bus-master enable and disable readback
Attached
Detach File
Event Timeline
Log In to Comment