Page MenuHomeFreeBSD

D31307.id92757.diff
No OneTemporary

D31307.id92757.diff

Index: share/man/man4/pci.4
===================================================================
--- share/man/man4/pci.4
+++ share/man/man4/pci.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 17, 2019
+.Dd July 26, 2021
.Dt PCI 4
.Os
.Sh NAME
@@ -419,6 +419,33 @@
of mapping.
Currently attempt to mmap an inactive BAR results in error.
.El
+.It PCIOCIOPORTIO
+This
+.Xr ioctl 2
+command allows users to perform I/O to I/O port BARs.
+The I/O request parameters are passed in a
+.Va struct pci_ioport_io
+structure, which has the following fields:
+.Bl -tag
+.It Vt struct pcisel pii_sel
+Describes the device to operate on.
+.It Vt int pii_op
+The operation to perform.
+Currently supported values are
+.Dv PCIIOPORT_READ
+and
+.Dv PCIIOPORT_WRITE .
+.It Vt uint32_t pii_bar
+The index of the BAR on which to operate.
+.It Vt uint32_t pii_offset
+The offset into the BAR at which to operate.
+.It Vt uint32_t pii_width
+The size of the I/O operation.
+1-byte, 2-byte and 4-byte operations are supported.
+.It Vt uint32_t pii_value
+For reads, the value is returned in this field.
+For writes, the caller specifies the value to be written in this field.
+.El
.El
.Sh LOADER TUNABLES
Tunables can be set at the
Index: sys/dev/pci/pci_user.c
===================================================================
--- sys/dev/pci/pci_user.c
+++ sys/dev/pci/pci_user.c
@@ -923,6 +923,84 @@
return (error);
}
+static int
+pci_bar_io(device_t pcidev, struct pci_ioport_io *pii)
+{
+ struct pci_map *pm;
+ struct resource *res;
+ bus_space_handle_t handle;
+ bus_space_tag_t tag;
+ uint32_t offset, width;
+ int error, bar;
+
+ if (pii->pii_op != PCIIOPORT_READ &&
+ pii->pii_op != PCIIOPORT_WRITE)
+ return (EINVAL);
+ if (pii->pii_bar > PCIR_MAX_BAR_0)
+ return (EINVAL);
+
+ bar = PCIR_BAR(pii->pii_bar);
+ pm = pci_find_bar(pcidev, bar);
+ if (pm == NULL)
+ return (EINVAL);
+
+ res = bus_alloc_resource_any(pcidev, SYS_RES_IOPORT, &bar, RF_ACTIVE);
+ if (res == NULL)
+ return (ENOENT);
+ handle = rman_get_bushandle(res);
+ tag = rman_get_bustag(res);
+
+ offset = pii->pii_offset;
+ width = pii->pii_width;
+
+ if (offset + width < offset ||
+ rman_get_size(res) < offset + width) {
+ error = EINVAL;
+ goto out;
+ }
+
+ error = 0;
+ switch (pii->pii_op) {
+ case PCIIOPORT_READ:
+ switch (pii->pii_width) {
+ case 1:
+ pii->pii_value = bus_space_read_1(tag, handle, offset);
+ break;
+ case 2:
+ pii->pii_value = bus_space_read_2(tag, handle, offset);
+ break;
+ case 4:
+ pii->pii_value = bus_space_read_4(tag, handle, offset);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+ case PCIIOPORT_WRITE:
+ switch (pii->pii_width) {
+ case 1:
+ bus_space_write_1(tag, handle, offset, pii->pii_value);
+ break;
+ case 2:
+ bus_space_write_2(tag, handle, offset, pii->pii_value);
+ break;
+ case 4:
+ bus_space_write_4(tag, handle, offset, pii->pii_value);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+ }
+
+out:
+ bus_release_resource(pcidev, SYS_RES_IOPORT, bar, res);
+
+ return (error);
+}
+
static int
pci_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
{
@@ -932,6 +1010,7 @@
struct pci_conf_io *cio = NULL;
struct pci_devinfo *dinfo;
struct pci_io *io;
+ struct pci_ioport_io *pii;
struct pci_bar_io *bio;
struct pci_list_vpd_io *lvio;
struct pci_match_conf *pattern_buf;
@@ -1302,6 +1381,19 @@
error = pcidev == NULL ? ENODEV : pci_bar_mmap(pcidev, pbm);
break;
+ case PCIOCIOPORTIO:
+ pii = (struct pci_ioport_io *)data;
+
+ pcidev = pci_find_dbsf(pii->pii_sel.pc_domain,
+ pii->pii_sel.pc_bus, pii->pii_sel.pc_dev,
+ pii->pii_sel.pc_func);
+ if (pcidev == NULL) {
+ error = ENODEV;
+ break;
+ }
+ error = pci_bar_io(pcidev, pii);
+ break;
+
default:
error = ENOTTY;
break;
Index: sys/sys/pciio.h
===================================================================
--- sys/sys/pciio.h
+++ sys/sys/pciio.h
@@ -151,6 +151,17 @@
int pbm_memattr;
};
+struct pci_ioport_io {
+ struct pcisel pii_sel; /* device to operate on */
+#define PCIIOPORT_READ 0x1
+#define PCIIOPORT_WRITE 0x2
+ int pii_op;
+ uint32_t pii_bar;
+ uint32_t pii_offset;
+ uint32_t pii_width;
+ uint32_t pii_value;
+};
+
#define PCIIO_BAR_MMAP_FIXED 0x01
#define PCIIO_BAR_MMAP_EXCL 0x02
#define PCIIO_BAR_MMAP_RW 0x04
@@ -163,5 +174,6 @@
#define PCIOCGETBAR _IOWR('p', 6, struct pci_bar_io)
#define PCIOCLISTVPD _IOWR('p', 7, struct pci_list_vpd_io)
#define PCIOCBARMMAP _IOWR('p', 8, struct pci_bar_mmap)
+#define PCIOCIOPORTIO _IOWR('p', 9, struct pci_ioport_io)
#endif /* !_SYS_PCIIO_H_ */

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 28, 5:19 AM (13 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32252810
Default Alt Text
D31307.id92757.diff (4 KB)

Event Timeline