From andrew@fubar.geek.nz  Mon May  7 09:20:51 2007
Return-Path: <andrew@fubar.geek.nz>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 5EC9216A400
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 May 2007 09:20:51 +0000 (UTC)
	(envelope-from andrew@fubar.geek.nz)
Received: from fep04.xtra.co.nz (fep04.xtra.co.nz [210.54.141.242])
	by mx1.freebsd.org (Postfix) with ESMTP id E8A8F13C459
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 May 2007 09:20:50 +0000 (UTC)
	(envelope-from andrew@fubar.geek.nz)
Received: from serv.int.fubar.geek.nz ([219.89.105.117])
          by fep04.xtra.co.nz with ESMTP
          id <20070507092047.ERNW25916.fep04.xtra.co.nz@serv.int.fubar.geek.nz>
          for <FreeBSD-gnats-submit@freebsd.org>;
          Mon, 7 May 2007 21:20:47 +1200
Message-Id: <20070507092047.9F6FC6200@serv.int.fubar.geek.nz>
Date: Mon,  7 May 2007 21:20:47 +1200 (NZST)
From: Andrew Turner <andrew@fubar.geek.nz>
Reply-To: Andrew Turner <andrew@fubar.geek.nz>
To: FreeBSD-gnats-submit@freebsd.org
Cc: andrew@fubar.geek.nz
Subject: Add support to set the node and type on a device on an ofw_bus bus
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         112477
>Category:       kern
>Synopsis:       [ofw] [patch] Add support to set the node and type on a device on an ofw_bus bus
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    marius
>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:  Wed May 23 09:20:03 GMT 2007
>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@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:
Responsible-Changed-From-To: freebsd-bugs->marius 
Responsible-Changed-By: marius 
Responsible-Changed-When: Sun May 13 14:40:42 UTC 2007 
Responsible-Changed-Why:  

Grab as the author of the ofw_bus subroutines. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=112477 

From: Andrew Turner <andrew@fubar.geek.nz>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/112477: [ofw] [patch] Add support to set the node and type
 on a device on an ofw_bus bus
Date: Wed, 23 May 2007 21:13:48 +1200

 --MP_cFXLceJSUT4VTCD4XGwyQI6
 Content-Type: text/plain; charset=US-ASCII
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline
 
 The attached patch is a replacement for the ofw_bus_subr.c parts of the
 first patch. It replaces the union with the __DECONST macro.
 
 Andrew
 --MP_cFXLceJSUT4VTCD4XGwyQI6
 Content-Type: text/x-patch; name=freebsd-ofw-bus-2.diff
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment; filename=freebsd-ofw-bus-2.diff
 
 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	23 May 2007 09:05:01 -0000
 @@ -116,6 +116,19 @@
  	return (obd->obd_node);
  }
  
 +int
 +ofw_bus_gen_set_node(device_t bus, device_t dev, phandle_t node)
 +{
 +	struct ofw_bus_devinfo *obd;
 +
 + 	obd = __DECONST(struct ofw_bus_devinfo *,OFW_BUS_GET_DEVINFO(bus, dev));
 +	if (obd == NULL)
 +		return (EINVAL);
 +	
 +	obd->obd_node = node;
 +	return (0);
 +}
 +
  const char *
  ofw_bus_gen_get_type(device_t bus, device_t dev)
  {
 @@ -126,3 +139,30 @@
  		return (NULL);
  	return (obd->obd_type);
  }
 +
 +int
 +ofw_bus_gen_set_type(device_t bus, device_t dev, const char *type)
 +{
 +	struct ofw_bus_devinfo *obd;
 +	char *str;
 +	size_t len;
 +
 + 	obd = __DECONST(struct ofw_bus_devinfo *,OFW_BUS_GET_DEVINFO(bus, dev));
 +	if (obd == 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->obd_type, M_OFWPROP);
 +
 +	/* Assign the new device type */
 +	obd->obd_type = str;
 +
 +	return (0);
 +}
 
 --MP_cFXLceJSUT4VTCD4XGwyQI6--
>Unformatted:
