Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161891814
D31307.id92746.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D31307.id92746.diff
View Options
Index: sys/dev/pci/pci_user.c
===================================================================
--- sys/dev/pci/pci_user.c
+++ sys/dev/pci/pci_user.c
@@ -923,6 +923,80 @@
return (error);
}
+static int
+pci_bar_io(device_t pcidev, struct pci_ioport_io *pii, bool write)
+{
+ 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_bar > PCIR_MAX_BAR_0)
+ return (EINVAL);
+
+ bar = PCIR_BAR(pii->pii_bar);
+ pm = pci_find_bar(pcidev, bar);
+ if (pm == NULL)
+ return (EINVAL);
+ if (!PCI_BAR_IO(pm->pm_value))
+ return (EIO);
+
+ 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 (rman_get_size(res) < offset ||
+ rman_get_size(res) < offset + width) {
+ error = EINVAL;
+ goto out;
+ }
+
+ error = 0;
+ if (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;
+ }
+ } else {
+ 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;
+ }
+ }
+
+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 +1006,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;
@@ -961,6 +1036,7 @@
#endif
case PCIOCGETBAR:
case PCIOCLISTVPD:
+ case PCIOCIOWRITE:
break;
default:
return (EPERM);
@@ -1302,6 +1378,22 @@
error = pcidev == NULL ? ENODEV : pci_bar_mmap(pcidev, pbm);
break;
+ case PCIOCIOREAD:
+ case PCIOCIOWRITE:
+ 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) {
+ printf("%s:%d\n", __func__, __LINE__);
+ error = ENODEV;
+ break;
+ }
+ error = pci_bar_io(pcidev, pii,
+ cmd == PCIOCIOREAD ? false : true);
+ break;
+
default:
error = ENOTTY;
break;
Index: sys/sys/pciio.h
===================================================================
--- sys/sys/pciio.h
+++ sys/sys/pciio.h
@@ -151,6 +151,14 @@
int pbm_memattr;
};
+struct pci_ioport_io {
+ struct pcisel pii_sel; /* device to operate on */
+ 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 +171,7 @@
#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 PCIOCIOREAD _IOWR('p', 9, struct pci_ioport_io)
+#define PCIOCIOWRITE _IOWR('p', 10, struct pci_ioport_io)
#endif /* !_SYS_PCIIO_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jul 8, 6:52 PM (6 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34856414
Default Alt Text
D31307.id92746.diff (3 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