Page MenuHomeFreeBSD

D31307.id92746.diff
No OneTemporary

D31307.id92746.diff

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

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)

Event Timeline