Date: Mon, 7 May 2007 21:20:47 +1200 (NZST) From: Andrew Turner <andrew@fubar.geek.nz> To: FreeBSD-gnats-submit@FreeBSD.org Cc: andrew@fubar.geek.nz Subject: kern/112477: Add support to set the node and type on a device on an ofw_bus bus Message-ID: <20070507092047.9F6FC6200@serv.int.fubar.geek.nz> Resent-Message-ID: <200705070930.l479U6Up071608@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070507092047.9F6FC6200>