From owner-freebsd-embedded@FreeBSD.ORG Wed Oct 23 14:39:21 2013 Return-Path: Delivered-To: freebsd-embedded@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 0E27B55D for ; Wed, 23 Oct 2013 14:39:21 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from mho-01-ewr.mailhop.org (mho-03-ewr.mailhop.org [204.13.248.66]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id D77152477 for ; Wed, 23 Oct 2013 14:39:20 +0000 (UTC) Received: from c-24-8-230-52.hsd1.co.comcast.net ([24.8.230.52] helo=damnhippie.dyndns.org) by mho-01-ewr.mailhop.org with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1VYzac-000JdL-6x for freebsd-embedded@FreeBSD.org; Wed, 23 Oct 2013 14:39:14 +0000 Received: from [172.22.42.240] (revolution.hippie.lan [172.22.42.240]) by damnhippie.dyndns.org (8.14.3/8.14.3) with ESMTP id r9NEdBNb043925 for ; Wed, 23 Oct 2013 08:39:11 -0600 (MDT) (envelope-from ian@FreeBSD.org) X-Mail-Handler: Dyn Standard SMTP by Dyn X-Originating-IP: 24.8.230.52 X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/sendlabs/outbound_abuse.html for abuse reporting information) X-MHO-User: U2FsdGVkX18ekcqDKMcOSbAKwBPPa+hC Subject: new ofw_search_compatible() From: Ian Lepore To: freebsd-embedded@FreeBSD.org Content-Type: multipart/mixed; boundary="=-ubnTihB6OA1sATM+QSy/" Date: Wed, 23 Oct 2013 08:39:10 -0600 Message-ID: <1382539150.92499.206.camel@revolution.hippie.lan> Mime-Version: 1.0 X-Mailer: Evolution 2.32.1 FreeBSD GNOME Team Port X-BeenThere: freebsd-embedded@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Dedicated and Embedded Systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Oct 2013 14:39:21 -0000 --=-ubnTihB6OA1sATM+QSy/ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit While creating drivers that work for a variety of SoCs, I increasingly find myself coding sequences such as: if (ofw_bus_is_compatible(dev, "fsl,imx51-fec")) sc->fectype = FECTYPE_IMX51; else if (ofw_bus_is_compatible(dev, "fsl,imx53-fec")) sc->fectype = FECTYPE_IMX53; else if (ofw_bus_is_compatible(dev, "fsl,imx6q-fec")) sc->fectype = FECTYPE_IMX6; else sc->fectype = FECTYPE_GENERIC; That's a short list as an example, eventually that driver may support a dozen SoCs. I'd like to add a helper routine that turns this into a table lookup, patch attached. Any objections? It turns sequences such as the above into: static struct ofw_compat_data compat_data[] = { {"fsl,imx51-fec", FECTYPE_IMX51}, {"fsl,imx53-fec", FECTYPE_IMX53}, {"fsl,imx6q-fec", FECTYPE_IMX6}, {NULL, FECTYPE_NONE}, }; /* ... */ sc->fectype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; The search routine by design can't return NULL unless you pass it a NULL table pointer. That lets you provide whatever "not found" value in the table-end sentry that works best for the way your code is structured. -- Ian --=-ubnTihB6OA1sATM+QSy/ Content-Disposition: inline; filename="ofw_search_compat.diff" Content-Type: text/x-patch; name="ofw_search_compat.diff"; charset="us-ascii" Content-Transfer-Encoding: 7bit Index: sys/dev/ofw/ofw_bus_subr.h =================================================================== --- sys/dev/ofw/ofw_bus_subr.h (revision 256962) +++ sys/dev/ofw/ofw_bus_subr.h (working copy) @@ -47,6 +47,11 @@ struct ofw_bus_iinfo { pcell_t opi_addrc; }; +struct ofw_compat_data { + const char *ocd_str; + uintptr_t ocd_data; +}; + /* Generic implementation of ofw_bus_if.m methods and helper routines */ int ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *, phandle_t); void ofw_bus_gen_destroy_devinfo(struct ofw_bus_devinfo *); @@ -74,6 +79,10 @@ void ofw_bus_find_iparent(phandle_t); int ofw_bus_is_compatible(device_t, const char *); int ofw_bus_is_compatible_strict(device_t, const char *); +/* Helper routine to search a list of compat props. */ +const struct ofw_compat_data * + ofw_bus_search_compatible(device_t, const struct ofw_compat_data *); + /* Helper routine for checking existence of a prop */ int ofw_bus_has_prop(device_t, const char *); Index: sys/dev/ofw/ofw_bus_subr.c =================================================================== --- sys/dev/ofw/ofw_bus_subr.c (revision 256962) +++ sys/dev/ofw/ofw_bus_subr.c (working copy) @@ -197,6 +197,21 @@ ofw_bus_is_compatible_strict(device_t dev, const c return (0); } +const struct ofw_compat_data * +ofw_bus_search_compatible(device_t dev, const struct ofw_compat_data *compat) +{ + + if (compat == NULL) + return NULL; + + for (; compat->ocd_str != NULL; ++compat) { + if (ofw_bus_is_compatible(dev, compat->ocd_str)) + break; + } + + return (compat); +} + int ofw_bus_has_prop(device_t dev, const char *propname) { --=-ubnTihB6OA1sATM+QSy/--