Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F171538464
D59477.id186119.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.id186119.diff
View Options
Index: share/man/man9/Makefile
===================================================================
--- share/man/man9/Makefile
+++ share/man/man9/Makefile
@@ -1823,8 +1823,10 @@
pci.9 pci_disable_busmaster.9 \
pci.9 pci_disable_io.9 \
pci.9 pci_enable_busmaster.9 \
+ pci.9 pci_enable_busmaster_checked.9 \
pci.9 pci_enable_io.9 \
pci.9 pci_enable_pme.9 \
+ pci.9 pci_fence_dma.9 \
pci.9 pci_find_bsf.9 \
pci.9 pci_find_cap.9 \
pci.9 pci_find_dbsf.9 \
Index: share/man/man9/pci.9
===================================================================
--- share/man/man9/pci.9
+++ 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 7, 2026
.Dt PCI 9
.Os
.Sh NAME
@@ -35,8 +35,10 @@
.Nm pci_disable_busmaster ,
.Nm pci_disable_io ,
.Nm pci_enable_busmaster ,
+.Nm pci_enable_busmaster_checked ,
.Nm pci_enable_io ,
.Nm pci_enable_pme ,
+.Nm pci_fence_dma ,
.Nm pci_find_bsf ,
.Nm pci_find_cap ,
.Nm pci_find_dbsf ,
@@ -98,9 +100,13 @@
.Ft int
.Fn pci_enable_busmaster "device_t dev"
.Ft int
+.Fn pci_enable_busmaster_checked "device_t dev"
+.Ft int
.Fn pci_enable_io "device_t dev" "int space"
.Ft void
.Fn pci_enable_pme "device_t dev"
+.Ft int
+.Fn pci_fence_dma "device_t dev"
.Ft device_t
.Fn pci_find_bsf "uint8_t bus" "uint8_t slot" "uint8_t func"
.Ft int
@@ -608,6 +614,35 @@
function clears this bit.
.Pp
The
+.Fn pci_enable_busmaster_checked
+function enables PCI bus mastering and verifies that the bus master enable bit
+is set.
+It returns
+.Er ENXIO
+if PCI configuration space is inaccessible,
+.Er EIO
+if the bit remains clear, or an error returned by
+.Fn pci_enable_busmaster .
+.Pp
+The
+.Fn pci_fence_dma
+function disables PCI bus mastering, verifies that the bus master enable bit
+is clear, and waits for pending PCI-express transactions to drain.
+It waits for at least 10 milliseconds and otherwise uses the maximum
+completion timeout configured for
+.Fa dev .
+The function may sleep.
+The function returns zero when DMA is fenced and otherwise returns
+.Er ENXIO
+if PCI configuration space becomes inaccessible,
+.Er EIO
+or an error returned by
+.Fn pci_disable_busmaster
+if bus mastering remains enabled, and
+.Er ETIMEDOUT
+if a present PCI-express function retains pending transactions.
+.Pp
+The
.Fn pci_enable_io
function enables memory or I/O port address decoding for the device
.Fa dev ,
Index: sys/dev/pci/pci.c
===================================================================
--- sys/dev/pci/pci.c
+++ sys/dev/pci/pci.c
@@ -7061,6 +7061,61 @@
}
}
+/* Enable bus mastering and verify the command-register write. */
+int
+pci_enable_busmaster_checked(device_t dev)
+{
+ uint16_t command;
+ int error;
+
+ command = pci_read_config(dev, PCIR_COMMAND, 2);
+ if (command == 0xffff)
+ return (ENXIO);
+ if ((command & PCIM_CMD_BUSMASTEREN) != 0)
+ return (0);
+
+ error = pci_enable_busmaster(dev);
+ command = pci_read_config(dev, PCIR_COMMAND, 2);
+ if (command == 0xffff)
+ return (ENXIO);
+ if ((command & PCIM_CMD_BUSMASTEREN) == 0)
+ return (error != 0 ? error : EIO);
+ return (0);
+}
+
+/*
+ * Disable bus mastering and wait for transactions initiated before the
+ * command-register write to drain.
+ *
+ * Returns zero once DMA is fenced, ENXIO if PCI configuration space becomes
+ * inaccessible, EIO or a bus-method error if bus mastering remains enabled,
+ * or ETIMEDOUT if a present PCI-express function retains pending
+ * transactions. This function may sleep.
+ */
+int
+pci_fence_dma(device_t dev)
+{
+ u_int timeout;
+ uint16_t command;
+ int error;
+
+ error = pci_disable_busmaster(dev);
+ command = pci_read_config(dev, PCIR_COMMAND, 2);
+ if (command == 0xffff)
+ return (ENXIO);
+ if ((command & PCIM_CMD_BUSMASTEREN) != 0)
+ return (error != 0 ? error : EIO);
+
+ timeout = max(pcie_get_max_completion_timeout(dev) / 1000, 10);
+ if (pcie_wait_for_pending_transactions(dev, timeout))
+ return (0);
+
+ /* Report a function which disappeared during the wait separately. */
+ if (pci_read_config(dev, PCIR_COMMAND, 2) == 0xffff)
+ return (ENXIO);
+ return (ETIMEDOUT);
+}
+
void
pcie_apei_error(device_t dev, int sev, uint8_t *aerp)
{
Index: sys/dev/pci/pcivar.h
===================================================================
--- sys/dev/pci/pcivar.h
+++ sys/dev/pci/pcivar.h
@@ -698,6 +698,8 @@
int pci_get_relaxed_ordering_enabled(device_t dev);
int pci_get_max_payload(device_t dev);
int pci_get_max_read_req(device_t dev);
+int pci_enable_busmaster_checked(device_t dev);
+int pci_fence_dma(device_t dev);
void pci_restore_state(device_t dev);
void pci_save_state(device_t dev);
int pci_set_max_read_req(device_t dev, int size);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Sep 12, 3:54 PM (14 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38801626
Default Alt Text
D59477.id186119.diff (4 KB)
Attached To
Mode
D59477: pci: Verify bus mastering changes and add a transaction drain
Attached
Detach File
Event Timeline
Log In to Comment