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