summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@herrb.eu>2022-05-01 20:05:59 +0200
committerMatthieu Herrb <matthieu@herrb.eu>2022-05-01 20:05:59 +0200
commite458df41cce8695617872b27823e03047e796b9a (patch)
tree1b1fc91e23e5329b1ab0877f1148340cda3937e4 /src
parentad97bd48fc501a869f59f8c03236bb9c8b12a14f (diff)
parent22a93f8b9b4a79eefbdd0b2c412526f6141ac7a8 (diff)
Merge remote-tracking branch 'origin/master' into obsd
Diffstat (limited to 'src')
-rw-r--r--src/Doxyfile2
-rw-r--r--src/common_io.c2
-rw-r--r--src/hurd_pci.c166
-rw-r--r--src/linux_sysfs.c6
-rw-r--r--src/x86_pci.c23
-rw-r--r--src/x86_pci.h8
6 files changed, 167 insertions, 40 deletions
diff --git a/src/Doxyfile b/src/Doxyfile
index 1185875..2f5d557 100644
--- a/src/Doxyfile
+++ b/src/Doxyfile
@@ -385,7 +385,7 @@ SHOW_DIRECTORIES = YES
# version control system). Doxygen will invoke the program by executing (via
# popen()) the command <command> <input-file>, where <command> is the value of
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the progam writes to standard output
+# provided by doxygen. Whatever the program writes to standard output
# is used as the file version. See the manual for examples.
FILE_VERSION_FILTER =
diff --git a/src/common_io.c b/src/common_io.c
index e9586ad..ad7d809 100644
--- a/src/common_io.c
+++ b/src/common_io.c
@@ -13,7 +13,7 @@
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY,
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN
diff --git a/src/hurd_pci.c b/src/hurd_pci.c
index 40c9925..2d10c5c 100644
--- a/src/hurd_pci.c
+++ b/src/hurd_pci.c
@@ -55,6 +55,7 @@
/* File names */
#define FILE_CONFIG_NAME "config"
+#define FILE_REGION_NAME "region"
#define FILE_ROM_NAME "rom"
/* Level in the fs tree */
@@ -68,6 +69,7 @@ typedef enum {
struct pci_system_hurd {
struct pci_system system;
+ mach_port_t root;
};
static int
@@ -149,8 +151,129 @@ pci_device_hurd_probe(struct pci_device *dev)
return 0;
}
+static void
+pci_system_hurd_destroy(void)
+{
+ struct pci_system_hurd *pci_sys_hurd = (struct pci_system_hurd *)pci_sys;
+
+ x86_disable_io();
+ mach_port_deallocate(mach_task_self(), pci_sys_hurd->root);
+}
+
+static int
+pci_device_hurd_map_range(struct pci_device *dev,
+ struct pci_device_mapping *map)
+{
+ struct pci_system_hurd *pci_sys_hurd = (struct pci_system_hurd *)pci_sys;
+ int err = 0;
+ file_t file = MACH_PORT_NULL;
+ memory_object_t robj, wobj, pager;
+ vm_offset_t offset;
+ vm_prot_t prot = VM_PROT_READ;
+ const struct pci_mem_region * const region = &dev->regions[map->region];
+ int flags = O_RDONLY;
+ char server[NAME_MAX];
+
+ if (map->flags & PCI_DEV_MAP_FLAG_WRITABLE) {
+ prot |= VM_PROT_WRITE;
+ flags = O_RDWR;
+ }
+
+ snprintf(server, NAME_MAX, "%04x/%02x/%02x/%01u/%s%01u",
+ dev->domain, dev->bus, dev->dev, dev->func,
+ FILE_REGION_NAME, map->region);
+
+ file = file_name_lookup_under (pci_sys_hurd->root, server, flags, 0);
+ if (! MACH_PORT_VALID (file)) {
+ return errno;
+ }
+
+ err = io_map (file, &robj, &wobj);
+ mach_port_deallocate (mach_task_self(), file);
+ if (err)
+ return err;
+
+ switch (prot & (VM_PROT_READ|VM_PROT_WRITE)) {
+ case VM_PROT_READ:
+ pager = robj;
+ if (wobj != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self(), wobj);
+ break;
+ case VM_PROT_READ|VM_PROT_WRITE:
+ if (robj == wobj) {
+ if (robj == MACH_PORT_NULL)
+ return EPERM;
+
+ pager = wobj;
+ /* Remove extra reference. */
+ mach_port_deallocate (mach_task_self (), pager);
+ }
+ else {
+ if (robj != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), robj);
+ if (wobj != MACH_PORT_NULL)
+ mach_port_deallocate (mach_task_self (), wobj);
+
+ return EPERM;
+ }
+ break;
+ default:
+ return EINVAL;
+ }
+
+ offset = map->base - region->base_addr;
+ err = vm_map (mach_task_self (), (vm_address_t *)&map->memory, map->size,
+ 0, 1,
+ pager, /* a memory object proxy containing only the region */
+ offset, /* offset from region start */
+ 0, prot, VM_PROT_ALL, VM_INHERIT_SHARE);
+ mach_port_deallocate (mach_task_self(), pager);
+
+ return err;
+}
+
+static int
+pci_device_hurd_unmap_range(struct pci_device *dev,
+ struct pci_device_mapping *map)
+{
+ int err;
+ err = pci_device_generic_unmap_range(dev, map);
+ map->memory = NULL;
+
+ return err;
+}
+
+static int
+pci_device_hurd_map_legacy(struct pci_device *dev, pciaddr_t base,
+ pciaddr_t size, unsigned map_flags, void **addr)
+{
+ struct pci_device_mapping map;
+ int err;
+
+ map.base = base;
+ map.size = size;
+ map.flags = map_flags;
+ err = pci_device_hurd_map_range(dev, &map);
+ *addr = map.memory;
+
+ return err;
+}
+
+static int
+pci_device_hurd_unmap_legacy(struct pci_device *dev, void *addr,
+ pciaddr_t size)
+{
+ struct pci_device_mapping map;
+
+ map.size = size;
+ map.flags = 0;
+ map.memory = addr;
+
+ return pci_device_hurd_unmap_range(dev, &map);
+}
+
/*
- * Read `nbytes' bytes from `reg' in device's configuretion space
+ * Read `nbytes' bytes from `reg' in device's configuration space
* and store them in `buf'.
*
* It's assumed that `nbytes' bytes are allocated in `buf'
@@ -339,7 +462,8 @@ enum_devices(mach_port_t pci_port, const char *parent, int domain,
if (lev > LEVEL_FUNC + 1) {
return 0;
}
- cwd_port = file_name_lookup_under (pci_port, parent, O_DIRECTORY | O_RDWR | O_EXEC, 0);
+ cwd_port = file_name_lookup_under (pci_port, parent,
+ O_DIRECTORY | O_RDONLY | O_EXEC, 0);
if (cwd_port == MACH_PORT_NULL) {
return 0;
}
@@ -391,7 +515,7 @@ enum_devices(mach_port_t pci_port, const char *parent, int domain,
snprintf(server, NAME_MAX, "./%04x/%02x/%02x/%01u/%s",
domain, bus, dev, func,
entry->d_name);
- device_port = file_name_lookup_under(pci_port, server, O_RDWR, 0);
+ device_port = file_name_lookup_under(pci_port, server, O_RDONLY, 0);
if (device_port == MACH_PORT_NULL) {
return 0;
}
@@ -461,17 +585,18 @@ enum_devices(mach_port_t pci_port, const char *parent, int domain,
pci_sys->num_devices++;
}
}
+ mach_port_deallocate (mach_task_self (), cwd_port);
return 0;
}
static const struct pci_system_methods hurd_pci_methods = {
- .destroy = pci_system_x86_destroy,
+ .destroy = pci_system_hurd_destroy,
.destroy_device = pci_device_hurd_destroy_device,
.read_rom = pci_device_hurd_read_rom,
.probe = pci_device_hurd_probe,
- .map_range = pci_device_x86_map_range,
- .unmap_range = pci_device_x86_unmap_range,
+ .map_range = pci_device_hurd_map_range,
+ .unmap_range = pci_device_hurd_unmap_range,
.read = pci_device_hurd_read,
.write = pci_device_hurd_write,
.fill_capabilities = pci_fill_capabilities_generic,
@@ -483,8 +608,8 @@ static const struct pci_system_methods hurd_pci_methods = {
.write32 = pci_device_x86_write32,
.write16 = pci_device_x86_write16,
.write8 = pci_device_x86_write8,
- .map_legacy = pci_device_x86_map_legacy,
- .unmap_legacy = pci_device_x86_unmap_legacy,
+ .map_legacy = pci_device_hurd_map_legacy,
+ .unmap_legacy = pci_device_hurd_unmap_legacy,
};
/* Get the name of the server using libpciaccess if any */
@@ -496,7 +621,8 @@ pci_system_hurd_create(void)
{
int err;
struct pci_system_hurd *pci_sys_hurd;
- mach_port_t device_master, pci_port;
+ mach_port_t device_master;
+ mach_port_t pci_port = MACH_PORT_NULL;
mach_port_t root = MACH_PORT_NULL;
if (&netfs_server_name && netfs_server_name
@@ -523,25 +649,29 @@ pci_system_hurd_create(void)
pci_sys->num_devices = 0;
- if ((err = get_privileged_ports (NULL, &device_master)) || (device_master == MACH_PORT_NULL)) {
- pci_system_cleanup();
- return err;
+ err = get_privileged_ports (NULL, &device_master);
+
+ if(!err && device_master != MACH_PORT_NULL) {
+ err = device_open (device_master, D_READ, "pci", &pci_port);
+ mach_port_deallocate (mach_task_self (), device_master);
}
- err = device_open (device_master, D_READ|D_WRITE, "pci", &pci_port);
- if (!err) {
- root = file_name_lookup_under (pci_port, ".", O_DIRECTORY | O_RDWR | O_EXEC, 0);
+ if (!err && pci_port != MACH_PORT_NULL) {
+ root = file_name_lookup_under (pci_port, ".", O_DIRECTORY | O_RDONLY | O_EXEC, 0);
+ device_close (pci_port);
+ mach_port_deallocate (mach_task_self (), pci_port);
}
- if (!root) {
- root = file_name_lookup (_SERVERS_BUS_PCI, O_RDWR, 0);
+ if (root == MACH_PORT_NULL) {
+ root = file_name_lookup (_SERVERS_BUS_PCI, O_RDONLY, 0);
}
- if (!root) {
+ if (root == MACH_PORT_NULL) {
pci_system_cleanup();
return errno;
}
+ pci_sys_hurd->root = root;
err = enum_devices (root, ".", -1, -1, -1, -1, LEVEL_DOMAIN);
if (err) {
pci_system_cleanup();
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index d022644..d79404e 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -336,9 +336,9 @@ pci_device_linux_sysfs_probe( struct pci_device * dev )
dev->regions[i].size = (high_addr
- dev->regions[i].base_addr) + 1;
- dev->regions[i].is_IO = (flags & 0x01);
- dev->regions[i].is_64 = (flags & 0x04);
- dev->regions[i].is_prefetchable = (flags & 0x08);
+ dev->regions[i].is_IO = (flags & 0x01) != 0;
+ dev->regions[i].is_64 = (flags & 0x04) != 0;
+ dev->regions[i].is_prefetchable = (flags & 0x08) != 0;
}
}
diff --git a/src/x86_pci.c b/src/x86_pci.c
index 565dbc8..86be0e7 100644
--- a/src/x86_pci.c
+++ b/src/x86_pci.c
@@ -263,6 +263,7 @@ map_dev_mem(void **dest, size_t mem_offset, size_t mem_size, int write)
}
err = device_open (master_device, mode, "mem", &devmem);
+ mach_port_deallocate (mach_task_self (), master_device);
if (err)
return err;
@@ -270,17 +271,21 @@ map_dev_mem(void **dest, size_t mem_offset, size_t mem_size, int write)
if (mem_size % pagesize)
mem_size += pagesize - (mem_size % pagesize);
- /* XXX: Mach should be fixed into supporting non-zero offset */
- err = device_map (devmem, prot, 0x0, mem_offset + mem_size, &pager, 0);
+ err = device_map (devmem, prot, mem_offset, mem_size, &pager, 0);
+ device_close (devmem);
+ mach_port_deallocate (mach_task_self (), devmem);
if (err)
return err;
err = vm_map (mach_task_self (), (vm_address_t *)dest, mem_size,
(vm_address_t) 0, /* mask */
1, /* anywhere? */
- pager, mem_offset,
+ pager, 0,
0, /* copy */
prot, VM_PROT_ALL, VM_INHERIT_SHARE);
+ mach_port_deallocate (mach_task_self (), pager);
+ if (err)
+ return err;
return err;
#else
@@ -908,19 +913,19 @@ pci_device_x86_unmap_range(struct pci_device *dev,
#else
-int
+static int
pci_device_x86_map_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
int err;
- if ( (err = map_dev_mem(&map->memory, map->base,
- map->size, map->flags & PCI_DEV_MAP_FLAG_WRITABLE)) )
+ if ( (err = map_dev_mem(&map->memory, map->base, map->size,
+ map->flags & PCI_DEV_MAP_FLAG_WRITABLE)))
return err;
return 0;
}
-int
+static int
pci_device_x86_unmap_range(struct pci_device *dev,
struct pci_device_mapping *map)
{
@@ -1099,7 +1104,7 @@ pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
outb(data, reg + handle->base);
}
-int
+static int
pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
pciaddr_t size, unsigned map_flags, void **addr)
{
@@ -1115,7 +1120,7 @@ pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
return err;
}
-int
+static int
pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
pciaddr_t size)
{
diff --git a/src/x86_pci.h b/src/x86_pci.h
index 22c9318..d36b48a 100644
--- a/src/x86_pci.h
+++ b/src/x86_pci.h
@@ -63,10 +63,6 @@
int x86_enable_io(void);
int x86_disable_io(void);
void pci_system_x86_destroy(void);
-int pci_device_x86_map_range(struct pci_device *dev,
- struct pci_device_mapping *map);
-int pci_device_x86_unmap_range(struct pci_device *dev,
- struct pci_device_mapping *map);
struct pci_io_handle *pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
struct pci_device *dev, pciaddr_t base, pciaddr_t size);
void pci_device_x86_close_io(struct pci_device *dev,
@@ -80,9 +76,5 @@ void pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
uint16_t data);
void pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
uint8_t data);
-int pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
- pciaddr_t size, unsigned map_flags, void **addr);
-int pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
- pciaddr_t size);
#endif /* X86_PCI_H */