Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F154219541
D31307.id92757.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
D31307.id92757.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D31307: pci: Add ioctls to perform I/O to I/O port BARs
Attached
Detach File
Event Timeline
Log In to Comment