]> mj.ucw.cz Git - pciutils.git/commitdiff
Hurd: Fix bug: pci_get_dev() and dev->aux
authorJoan Lledó <jlledom@member.fsf.org>
Sun, 22 Mar 2020 10:51:39 +0000 (11:51 +0100)
committerJoan Lledó <jlledom@member.fsf.org>
Sun, 22 Mar 2020 10:51:39 +0000 (11:51 +0100)
Allow clients to read and write from a device w/o a bus scan

lib/hurd.c

index 8cc948b1ad53f56a1e6bdcb6c2c404e5772183a9..713727d28d810cf64ce23622c14e81221f8c524e 100644 (file)
@@ -73,6 +73,7 @@ static void
 hurd_init_dev(struct pci_dev *d)
 {
   d->aux = pci_malloc(d->access, sizeof(mach_port_t));
+  *((mach_port_t *) d->aux) = 0;
 }
 
 /* Deallocate the port and free its space */
@@ -87,6 +88,20 @@ hurd_cleanup_dev(struct pci_dev *d)
   pci_mfree(d->aux);
 }
 
+static void
+device_port_lookup(struct pci_dev *d)
+{
+  mach_port_t device_port;
+  char server[NAME_MAX];
+
+  snprintf(server, NAME_MAX, "%s/%04x/%02x/%02x/%01u/%s",
+     _SERVERS_BUS_PCI, d->domain, d->bus, d->dev, d->func,
+     FILE_CONFIG_NAME);
+  device_port = file_name_lookup(server, 0, 0);
+
+  *((mach_port_t *) d->aux) = device_port;
+}
+
 /* Walk through the FS tree to see what is allowed for us */
 static void
 enum_devices(const char *parent, struct pci_access *a, int domain, int bus,
@@ -96,10 +111,8 @@ enum_devices(const char *parent, struct pci_access *a, int domain, int bus,
   DIR *dir;
   struct dirent *entry;
   char path[NAME_MAX];
-  char server[NAME_MAX];
   uint32_t vd;
   uint8_t ht;
-  mach_port_t device_port;
   struct pci_dev *d;
 
   dir = opendir(parent);
@@ -167,22 +180,22 @@ enum_devices(const char *parent, struct pci_access *a, int domain, int bus,
            continue;
 
          /* We found an available virtual device, add it to our list */
-         snprintf(server, NAME_MAX, "%s/%04x/%02x/%02x/%01u/%s",
-                  _SERVERS_BUS_PCI, domain, bus, dev, func, entry->d_name);
-         device_port = file_name_lookup(server, 0, 0);
-         if (device_port == MACH_PORT_NULL)
+         d = pci_alloc_dev(a);
+         d->domain = domain;
+         d->bus = bus;
+         d->dev = dev;
+         d->func = func;
+
+         /* Get the arbiter port */
+         device_port_lookup(d);
+         if (d->aux == MACH_PORT_NULL)
            {
              if (closedir(dir) < 0)
                a->warning("Cannot close directory: %s (%s)", parent,
                           strerror(errno));
-             a->error("Cannot open %s", server);
+             a->error("Cannot find the PCI arbiter");
            }
 
-         d = pci_alloc_dev(a);
-         *((mach_port_t *) d->aux) = device_port;
-         d->bus = bus;
-         d->dev = dev;
-         d->func = func;
          pci_link_dev(a, d);
 
          vd = pci_read_long(d, PCI_VENDOR_ID);
@@ -220,7 +233,17 @@ hurd_read(struct pci_dev *d, int pos, byte * buf, int len)
   mach_port_t device_port;
 
   nread = len;
+  if (*((mach_port_t *) d->aux) == 0)
+    {
+      /* We still don't have the port for this device */
+      device_port_lookup(d);
+      if (d->aux == MACH_PORT_NULL)
+       {
+         d->access->error("Cannot find the PCI arbiter");
+       }
+    }
   device_port = *((mach_port_t *) d->aux);
+
   if (len > 4)
     err = !pci_generic_block_read(d, pos, buf, nread);
   else
@@ -259,7 +282,17 @@ hurd_write(struct pci_dev *d, int pos, byte * buf, int len)
   mach_port_t device_port;
 
   nwrote = len;
+  if (*((mach_port_t *) d->aux) == 0)
+    {
+      /* We still don't have the port for this device */
+      device_port_lookup(d);
+      if (d->aux == MACH_PORT_NULL)
+       {
+         d->access->error("Cannot find the PCI arbiter");
+       }
+    }
   device_port = *((mach_port_t *) d->aux);
+
   if (len > 4)
     err = !pci_generic_block_write(d, pos, buf, len);
   else