kern/112477: Add support to set the node and type on a device on an
ofw_bus bus
Andrew Turner
andrew at fubar.geek.nz
Mon May 7 09:30:06 UTC 2007
>Number: 112477
>Category: kern
>Synopsis: Add support to set the node and type on a device on an ofw_bus bus
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: update
>Submitter-Id: current-users
>Arrival-Date: Mon May 07 09:30:05 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Andrew Turner
>Release: FreeBSD 5.5-RC1 i386
>Organization:
>Environment:
System: FreeBSD serv.int.fubar.geek.nz 5.5-RC1 FreeBSD 5.5-RC1 #0: Mon May 15 14:09:18 NZST 2006 root at serv.int.fubar.geek.nz:/usr/obj/usr/src/sys/GENERIC i386
>Description:
The attached patch adds the ability to set the Openfirmware node and device type on a bus. This will be used by the PowerPC nexus bus to replace nexus_set_device_type and nexus_set_node.
This patch has been tested on a PowerPC G4 with a patch to call this rather than the nexus_* calls.
>How-To-Repeat:
>Fix:
--- freebsd-ofw-bus.diff begins here ---
Index: sys/dev/ofw/ofw_bus.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ofw/ofw_bus.h,v
retrieving revision 1.1
diff -u -u -r1.1 ofw_bus.h
--- sys/dev/ofw/ofw_bus.h 12 Aug 2004 17:41:29 -0000 1.1
+++ sys/dev/ofw/ofw_bus.h 6 May 2007 10:39:21 -0000
@@ -63,6 +63,13 @@
return (OFW_BUS_GET_NODE(device_get_parent(dev), dev));
}
+static __inline int
+ofw_bus_set_node(device_t dev, phandle_t node)
+{
+
+ return (OFW_BUS_SET_NODE(device_get_parent(dev), dev, node));
+}
+
static __inline const char *
ofw_bus_get_type(device_t dev)
{
@@ -70,4 +77,11 @@
return (OFW_BUS_GET_TYPE(device_get_parent(dev), dev));
}
+static __inline int
+ofw_bus_set_type(device_t dev, const char *type)
+{
+
+ return (OFW_BUS_SET_TYPE(device_get_parent(dev), dev, type));
+}
+
#endif /* !_DEV_OFW_OFW_BUS_H_ */
Index: sys/dev/ofw/ofw_bus_if.m
===================================================================
RCS file: /cvsroot/src/sys/dev/ofw/ofw_bus_if.m,v
retrieving revision 1.3
diff -u -u -r1.3 ofw_bus_if.m
--- sys/dev/ofw/ofw_bus_if.m 22 Nov 2005 16:37:45 -0000 1.3
+++ sys/dev/ofw/ofw_bus_if.m 6 May 2007 10:38:27 -0000
@@ -55,7 +55,9 @@
static ofw_bus_get_model_t ofw_bus_default_get_model;
static ofw_bus_get_name_t ofw_bus_default_get_name;
static ofw_bus_get_node_t ofw_bus_default_get_node;
+ static ofw_bus_set_node_t ofw_bus_default_set_node;
static ofw_bus_get_type_t ofw_bus_default_get_type;
+ static ofw_bus_set_type_t ofw_bus_default_set_type;
static const struct ofw_bus_devinfo *
ofw_bus_default_get_devinfo(device_t bus, device_t dev)
@@ -92,12 +94,25 @@
return (0);
}
+ static int
+ ofw_bus_default_set_node(device_t bus, device_t dev, phandle_t node)
+ {
+
+ return (EOPNOTSUPP);
+ }
+
static const char *
ofw_bus_default_get_type(device_t bus, device_t dev)
{
return (NULL);
}
+
+ int
+ ofw_bus_default_set_type(device_t bus, device_t dev, const char *type)
+ {
+ return (EOPNOTSUPP);
+ }
};
# Get the ofw_bus_devinfo struct for the device dev on the bus. Used for bus
@@ -137,9 +152,25 @@
device_t dev;
} DEFAULT ofw_bus_default_get_node;
+# Set the firmware node for the device dev on the bus. The default method will
+# return EOPNOTSUPP, which means setting the node is unimplemented.
+METHOD int set_node {
+ device_t bus;
+ device_t dev;
+ phandle_t node;
+} DEFAULT ofw_bus_default_set_node;
+
# Get the firmware device type for the device dev on the bus. The default
# method will return NULL, which means the device doesn't have such a property.
METHOD const char * get_type {
device_t bus;
device_t dev;
} DEFAULT ofw_bus_default_get_type;
+
+# Set the firmware device type for the device dev on the bus. The default
+# method will return EOPNOTSUPP, which means setting the type is unimplemented.
+METHOD int set_type {
+ device_t bus;
+ device_t dev;
+ const char *type;
+} DEFAULT ofw_bus_default_set_type;
Index: sys/dev/ofw/ofw_bus_subr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ofw/ofw_bus_subr.c,v
retrieving revision 1.1
diff -u -u -r1.1 ofw_bus_subr.c
--- sys/dev/ofw/ofw_bus_subr.c 22 Nov 2005 16:37:45 -0000 1.1
+++ sys/dev/ofw/ofw_bus_subr.c 7 May 2007 08:54:54 -0000
@@ -116,6 +116,23 @@
return (obd->obd_node);
}
+int
+ofw_bus_gen_set_node(device_t bus, device_t dev, phandle_t node)
+{
+ /* This union is to de-const the return value of OFW_BUS_GET_DEVINFO */
+ union {
+ const struct ofw_bus_devinfo *cst;
+ struct ofw_bus_devinfo *ptr;
+ } obd;
+
+ obd.cst = OFW_BUS_GET_DEVINFO(bus, dev);
+ if (obd.cst == NULL)
+ return (EINVAL);
+
+ obd.ptr->obd_node = node;
+ return (0);
+}
+
const char *
ofw_bus_gen_get_type(device_t bus, device_t dev)
{
@@ -126,3 +143,34 @@
return (NULL);
return (obd->obd_type);
}
+
+int
+ofw_bus_gen_set_type(device_t bus, device_t dev, const char *type)
+{
+ /* This union is to de-const the return value of OFW_BUS_GET_DEVINFO */
+ union {
+ const struct ofw_bus_devinfo *cst;
+ struct ofw_bus_devinfo *ptr;
+ } obd;
+ char *str;
+ size_t len;
+
+ obd.cst = OFW_BUS_GET_DEVINFO(bus, dev);
+ if (obd.cst == NULL)
+ return (EINVAL);
+
+ len = strlen(type);
+ /* This is M_NOWAIT as we don't know if the caller can wait or not */
+ str = malloc(len + 1, M_OFWPROP, M_NOWAIT | M_ZERO);
+ if (str == NULL)
+ return (ENOMEM);
+
+ /* Copy the new type to the string and free the old type */
+ bcopy(type, str, len);
+ free(obd.cst->obd_type, M_OFWPROP);
+
+ /* Assign the new device type */
+ obd.ptr->obd_type = str;
+
+ return (0);
+}
Index: sys/dev/ofw/ofw_bus_subr.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ofw/ofw_bus_subr.h,v
retrieving revision 1.1
diff -u -u -r1.1 ofw_bus_subr.h
--- sys/dev/ofw/ofw_bus_subr.h 22 Nov 2005 16:37:45 -0000 1.1
+++ sys/dev/ofw/ofw_bus_subr.h 6 May 2007 10:25:55 -0000
@@ -44,6 +44,8 @@
ofw_bus_get_model_t ofw_bus_gen_get_model;
ofw_bus_get_name_t ofw_bus_gen_get_name;
ofw_bus_get_node_t ofw_bus_gen_get_node;
+ofw_bus_set_node_t ofw_bus_gen_set_node;
ofw_bus_get_type_t ofw_bus_gen_get_type;
+ofw_bus_set_type_t ofw_bus_gen_set_type;
#endif /* !_DEV_OFW_OFW_BUS_SUBR_H_ */
--- freebsd-ofw-bus.diff ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list