[haiku-commits] Change in haiku[master]: freebsd_network: Apply empty size and type check to IO ports.

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 11 Jul 2020 22:41:21 +0000

From Michael Lotz <mmlr@xxxxxxxx>:

Michael Lotz has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/3025 ;)


Change subject: freebsd_network: Apply empty size and type check to IO ports.
......................................................................

freebsd_network: Apply empty size and type check to IO ports.

Factor out the conversion to BAR index and hand the pci_info to both
memory and IO port allocation functions. Then apply the same checks
in the IO port case as are done for memory.

This aligns with what is done on FreeBSD.
---
M src/libs/compat/freebsd_network/bus.cpp
1 file changed, 47 insertions(+), 22 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/25/3025/1

diff --git a/src/libs/compat/freebsd_network/bus.cpp 
b/src/libs/compat/freebsd_network/bus.cpp
index fd696b4..00677eb 100644
--- a/src/libs/compat/freebsd_network/bus.cpp
+++ b/src/libs/compat/freebsd_network/bus.cpp
@@ -110,29 +110,19 @@


 static int
-bus_alloc_mem_resource(device_t dev, struct resource *res, int regid)
+bus_alloc_mem_resource(device_t dev, struct resource *res, pci_info *info,
+       int bar_index)
 {
-       pci_info *info = &((struct root_device_softc 
*)dev->root->softc)->pci_info;
-
-       // check the offset really is of a BAR
-       if (regid < PCI_base_registers || (regid % sizeof(uint32) != 0)
-               || (regid >= PCI_base_registers + 6 * (int)sizeof(uint32)))
-               return -1;
-
-       // turn offset into array index
-       regid -= PCI_base_registers;
-       regid /= sizeof(uint32);
-
-       uint32 addr = info->u.h0.base_registers[regid];
-       uint32 size = info->u.h0.base_register_sizes[regid];
-       uchar flags = info->u.h0.base_register_flags[regid];
+       uint32 addr = info->u.h0.base_registers[bar_index];
+       uint32 size = info->u.h0.base_register_sizes[bar_index];
+       uchar flags = info->u.h0.base_register_flags[bar_index];

        // reject empty regions
        if (size == 0)
                return -1;

        // reject I/O space
-       if (flags & PCI_address_space)
+       if ((flags & PCI_address_space) != 0)
                return -1;

        // TODO: check flags & PCI_address_prefetchable ?
@@ -155,18 +145,46 @@


 static int
-bus_alloc_ioport_resource(device_t dev, struct resource *res, int regid)
+bus_alloc_ioport_resource(device_t dev, struct resource *res, pci_info *info,
+       int bar_index)
 {
+       uint32 size = info->u.h0.base_register_sizes[bar_index];
+       uchar flags = info->u.h0.base_register_flags[bar_index];
+
+       // reject empty regions
+       if (size == 0)
+               return -1;
+
+       // reject memory space
+       if ((flags & PCI_address_space) == 0)
+               return -1;
+
        // enable this I/O resource
        if (pci_enable_io(dev, SYS_RES_IOPORT) != 0)
                return -1;

        res->r_bustag = X86_BUS_SPACE_IO;
-       res->r_bushandle = pci_read_config(dev, regid, 4) & PCI_address_io_mask;
+       res->r_bushandle = info->u.h0.base_registers[bar_index];
        return 0;
 }


+static int
+bus_register_to_bar_index(pci_info *info, int regid)
+{
+       // check the offset really is of a BAR
+       if (regid < PCI_base_registers || (regid % sizeof(uint32) != 0)
+               || (regid >= PCI_base_registers + 6 * (int)sizeof(uint32))) {
+               return -1;
+       }
+
+       // turn offset into array index
+       regid -= PCI_base_registers;
+       regid /= sizeof(uint32);
+       return regid;
+}
+
+
 struct resource *
 bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start,
        unsigned long end, unsigned long count, uint32 flags)
@@ -198,10 +216,17 @@
                        res->r_bushandle = info->u.h0.interrupt_line + *rid - 1;
                        result = 0;
                }
-       } else if (type == SYS_RES_MEMORY)
-               result = bus_alloc_mem_resource(dev, res, *rid);
-       else if (type == SYS_RES_IOPORT)
-               result = bus_alloc_ioport_resource(dev, res, *rid);
+       } else {
+               pci_info *info
+                       = &((struct root_device_softc 
*)dev->root->softc)->pci_info;
+               int bar_index = bus_register_to_bar_index(info, *rid);
+               if (bar_index >= 0) {
+                       if (type == SYS_RES_MEMORY)
+                               result = bus_alloc_mem_resource(dev, res, info, 
bar_index);
+                       else if (type == SYS_RES_IOPORT)
+                               result = bus_alloc_ioport_resource(dev, res, 
info, bar_index);
+               }
+       }

        if (result < 0) {
                free(res);

--
To view, visit https://review.haiku-os.org/c/haiku/+/3025
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Ib4bd28fd861959a467ba676de22efb1f97e5a27c
Gerrit-Change-Number: 3025
Gerrit-PatchSet: 1
Gerrit-Owner: Michael Lotz <mmlr@xxxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: freebsd_network: Apply empty size and type check to IO ports. - Gerrit