Author: jhb
Date: Thu Nov  1 21:46:37 2018
New Revision: 340022
URL: https://svnweb.freebsd.org/changeset/base/340022

Log:
  Add support for port unit wiring to cxgbe(4).
  
  - Add a bus_child_location_str method to the nexus drivers that prints
    out 'port=N' as the location string exported via devinfo and the
    '%location' sysctl node.
  
  - We can't use a bus_hint_device_unit to wire the unit numbers of
    devices with a fixed devclass as the device gets assigned a unit in
    make_device() before the device creator can set softc, etc.
    Instead, when adding a child device, use a helper function much like
    a bus_hint_device_unit method to look for wiring hints or to return
    -1 to let the system choose a unit number.  This function requires
    an "at" hint for the port pointing to the nexus device and a "port"
    hint listing the port number.  For example:
  
  hint.cxl.4.at="t5nex0"
  hint.cxl.4.port="0"
  
    wires cxl4 to the first port on the t5nex0 adapter.
  
  Requested by: gallatin
  MFC after:    2 months

Modified:
  head/sys/dev/cxgbe/t4_main.c

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c        Thu Nov  1 21:39:33 2018        
(r340021)
+++ head/sys/dev/cxgbe/t4_main.c        Thu Nov  1 21:46:37 2018        
(r340022)
@@ -92,6 +92,7 @@ __FBSDID("$FreeBSD$");
 static int t4_probe(device_t);
 static int t4_attach(device_t);
 static int t4_detach(device_t);
+static int t4_child_location_str(device_t, device_t, char *, size_t);
 static int t4_ready(device_t);
 static int t4_read_port_device(device_t, int, device_t *);
 static device_method_t t4_methods[] = {
@@ -99,6 +100,8 @@ static device_method_t t4_methods[] = {
        DEVMETHOD(device_attach,        t4_attach),
        DEVMETHOD(device_detach,        t4_detach),
 
+       DEVMETHOD(bus_child_location_str, t4_child_location_str),
+
        DEVMETHOD(t4_is_main_ready,     t4_ready),
        DEVMETHOD(t4_read_port_device,  t4_read_port_device),
 
@@ -158,6 +161,8 @@ static device_method_t t5_methods[] = {
        DEVMETHOD(device_attach,        t4_attach),
        DEVMETHOD(device_detach,        t4_detach),
 
+       DEVMETHOD(bus_child_location_str, t4_child_location_str),
+
        DEVMETHOD(t4_is_main_ready,     t4_ready),
        DEVMETHOD(t4_read_port_device,  t4_read_port_device),
 
@@ -191,6 +196,8 @@ static device_method_t t6_methods[] = {
        DEVMETHOD(device_attach,        t4_attach),
        DEVMETHOD(device_detach,        t4_detach),
 
+       DEVMETHOD(bus_child_location_str, t4_child_location_str),
+
        DEVMETHOD(t4_is_main_ready,     t4_ready),
        DEVMETHOD(t4_read_port_device,  t4_read_port_device),
 
@@ -837,6 +844,24 @@ t4_init_devnames(struct adapter *sc)
 }
 
 static int
+t4_ifnet_unit(struct adapter *sc, struct port_info *pi)
+{
+       const char *parent, *name;
+       long value;
+       int line, unit;
+
+       line = 0;
+       parent = device_get_nameunit(sc->dev);
+       name = sc->names->ifnet_name;
+       while (resource_find_dev(&line, name, &unit, "at", parent) == 0) {
+               if (resource_long_value(name, unit, "port", &value) == 0 &&
+                   value == pi->port_id)
+                       return (unit);
+       }
+       return (-1);
+}
+
+static int
 t4_attach(device_t dev)
 {
        struct adapter *sc;
@@ -1037,7 +1062,8 @@ t4_attach(device_t dev)
                        pi->flags |= FIXED_IFMEDIA;
                PORT_UNLOCK(pi);
 
-               pi->dev = device_add_child(dev, sc->names->ifnet_name, -1);
+               pi->dev = device_add_child(dev, sc->names->ifnet_name,
+                   t4_ifnet_unit(sc, pi));
                if (pi->dev == NULL) {
                        device_printf(dev,
                            "failed to add device for port %d.\n", i);
@@ -1250,6 +1276,16 @@ done:
                t4_sysctls(sc);
 
        return (rc);
+}
+
+static int
+t4_child_location_str(device_t bus, device_t dev, char *buf, size_t buflen)
+{
+       struct port_info *pi;
+
+       pi = device_get_softc(dev);
+       snprintf(buf, buflen, "port=%d", pi->port_id);
+       return (0);
 }
 
 static int
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to