summaryrefslogtreecommitdiff
path: root/pci-arbiter/main.c
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2021-03-09 00:04:56 +1100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2021-03-08 22:17:03 +0100
commitb261eb886e4ee068515484727955e416517a03b4 (patch)
treeedf55004020d488a008e1cd8ab70a94724e89094 /pci-arbiter/main.c
parenta5fc9f2e767f034830ee5b179123b093180bf259 (diff)
pci-arbiter: Introduce machdev into this server
* pci-arbiter/Makefile Add machdev lib and simplify * pci-arbiter/main.c (pci_device_{open,close,shutdown}): New methods (netfs_server_func): Thread the demuxer loop (pcifs_startup): Custom startup method (main): Use machdev for server and detach worker threads * pci-arbiter/options.{c,h} Add disk-server-task and priv ports * pci-arbiter/startup-ops.c Delete file Message-Id: <20210308130457.693821-4-damien@zamaudio.com>
Diffstat (limited to 'pci-arbiter/main.c')
-rw-r--r--pci-arbiter/main.c187
1 files changed, 179 insertions, 8 deletions
diff --git a/pci-arbiter/main.c b/pci-arbiter/main.c
index 181bdee2..efb9f65c 100644
--- a/pci-arbiter/main.c
+++ b/pci-arbiter/main.c
@@ -24,7 +24,12 @@
#include <fcntl.h>
#include <version.h>
#include <argp.h>
+#include <unistd.h>
#include <hurd/netfs.h>
+#include <hurd/ports.h>
+#include <hurd/fsys.h>
+#include <device/device.h>
+#include <sys/mman.h>
#include <pci_S.h>
#include <startup_notify_S.h>
@@ -34,7 +39,9 @@
#include "libnetfs/fsys_S.h"
#include "libports/interrupt_S.h"
#include "libnetfs/ifsock_S.h"
+#include "libmachdev/machdev.h"
#include <pciaccess.h>
+#include <pthread.h>
#include "pcifs.h"
#include "startup.h"
@@ -46,6 +53,96 @@ int netfs_maxsymlinks = 0;
char *netfs_server_name = "pci-arbiter";
char *netfs_server_version = HURD_VERSION;
+static mach_port_t pci_control_port;
+
+
+static io_return_t
+pci_device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
+ dev_mode_t mode, char *name, device_t * devp,
+ mach_msg_type_name_t * devicePoly)
+{
+ io_return_t err = D_SUCCESS;
+ mach_port_t dev_master, root;
+ string_t retry_name;
+ retry_type retry;
+ uid_t idlist[] = {0, 0, 0};
+
+ if (strncmp(name, "pci", 3))
+ err = D_NO_SUCH_DEVICE;
+
+ /* Fall back to opening kernel device master */
+ if (err)
+ {
+ err = get_privileged_ports(NULL, &dev_master);
+ if (err)
+ return err;
+ if (dev_master == MACH_PORT_NULL)
+ return D_NO_SUCH_DEVICE;
+ err = device_open (dev_master, mode, name, devp);
+ if (err)
+ return err;
+ *devicePoly = MACH_MSG_TYPE_MOVE_SEND;
+ return D_SUCCESS;
+ }
+
+ err = fsys_getroot(pci_control_port, MACH_PORT_NULL, MACH_MSG_TYPE_COPY_SEND,
+ idlist, 3, idlist, 3, 0,
+ &retry, retry_name, &root);
+ if (err)
+ return err;
+
+ *devp = root;
+ *devicePoly = MACH_MSG_TYPE_COPY_SEND;
+ return D_SUCCESS;
+}
+
+static io_return_t
+pci_device_close (void *d)
+{
+ ports_port_deref (&pci_control_port);
+ return 0;
+}
+
+static void
+pci_device_shutdown (mach_port_t dosync_handle)
+{
+ struct port_info *inpi = ports_lookup_port (netfs_port_bucket, dosync_handle,
+ pci_shutdown_notify_class);
+
+ if (!inpi)
+ return;
+
+ // Free all libpciaccess resources
+ pci_system_cleanup ();
+
+ ports_port_deref (inpi);
+
+ ports_destroy_right (&pci_control_port);
+
+ netfs_shutdown (FSYS_GOAWAY_FORCE);
+}
+
+static struct machdev_device_emulation_ops pci_arbiter_emulation_ops = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ pci_device_open,
+ pci_device_close,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ pci_device_shutdown,
+};
+
int
netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
{
@@ -67,25 +164,83 @@ netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
return FALSE;
}
+static void *
+netfs_server_func (void *arg)
+{
+ error_t err;
+
+ do
+ {
+ ports_manage_port_operations_multithread (netfs_port_bucket,
+ netfs_demuxer,
+ 1000 * 60 * 2, /* two minutes thread */
+ 1000 * 60 * 10,/* ten minutes server */
+ 0);
+ err = netfs_shutdown (0);
+ }
+ while (err);
+ return NULL;
+}
+
+
+static mach_port_t
+pcifs_startup(mach_port_t bootstrap, int flags)
+{
+ error_t err;
+ mach_port_t realnode;
+ struct port_info *newpi;
+
+ err = ports_create_port (netfs_control_class, netfs_port_bucket,
+ sizeof (struct port_info), &newpi);
+ if (!err)
+ {
+ pci_control_port = ports_get_send_right (newpi);
+ err = fsys_startup (bootstrap, flags, pci_control_port, MACH_MSG_TYPE_COPY_SEND,
+ &realnode);
+ assert_perror_backtrace (err);
+ }
+ if (err)
+ error (11, err, "Translator startup failure: fsys_startup");
+
+ return realnode;
+}
+
int
main (int argc, char **argv)
{
error_t err;
mach_port_t bootstrap;
+ mach_port_t disk_server_task;
+ pthread_t t, nt;
/* Parse options */
alloc_file_system (&fs);
argp_parse (netfs_runtime_argp, argc, argv, 0, 0, 0);
+ disk_server_task = fs->params.disk_server_task;
- task_get_bootstrap_port (mach_task_self (), &bootstrap);
- if (bootstrap == MACH_PORT_NULL)
- error (1, 0, "must be started as a translator");
-
+ if (disk_server_task != MACH_PORT_NULL)
+ {
+ machdev_register (&pci_arbiter_emulation_ops);
+ machdev_device_init ();
+ machdev_trivfs_init (disk_server_task, "pci", "/servers/bus/pci", &bootstrap);
+ err = pthread_create (&t, NULL, machdev_server, NULL);
+ if (err)
+ error (1, err, "Creating machdev thread");
+ pthread_detach (t);
+ }
+ else
+ {
+ task_get_bootstrap_port (mach_task_self (), &bootstrap);
+ if (bootstrap == MACH_PORT_NULL)
+ error (1, 0, "must be started as a translator");
+ }
/* Initialize netfs and start the translator. */
netfs_init ();
err = maptime_map (0, 0, &pcifs_maptime);
if (err)
+ err = maptime_map (1, 0, &pcifs_maptime);
+ if (err)
error (1, err, "mapping time");
/* Start the PCI system: NB: pciaccess will choose x86 first and take lock */
@@ -93,8 +248,18 @@ main (int argc, char **argv)
if (err)
error (1, err, "Starting the PCI system");
- /* Create the PCI filesystem */
- err = init_file_system (netfs_startup (bootstrap, O_READ), fs);
+ if (disk_server_task != MACH_PORT_NULL)
+ machdev_trivfs_server(bootstrap);
+ /* Timer started, quickly do all these next, before we call rump_init */
+
+ /* Create the root node first */
+ err = init_root_node ();
+ if (err)
+ error (1, err, "Creating the root node");
+
+ pcifs_startup (bootstrap, O_READ);
+
+ err = init_file_system (fs);
if (err)
error (1, err, "Creating the PCI filesystem");
@@ -108,13 +273,19 @@ main (int argc, char **argv)
if (err)
error (1, err, "Setting permissions");
+ err = pthread_create (&nt, NULL, netfs_server_func, NULL);
+ if (err)
+ error (1, err, "Creating netfs loop thread");
+ pthread_detach (nt);
+
/*
* Ask init to tell us when the system is going down,
* so we can try to be friendly to our correspondents on the network.
*/
arrange_shutdown_notification ();
- netfs_server_loop (); /* Never returns. */
-
+ /* Let the other threads do their job */
+ pthread_exit(NULL);
+ /* Never reached */
return 0;
}