svn commit: r269541 - in head: . sys/boot/kshim sys/boot/usb sys/boot/usb/tools

Brooks Davis brooks at FreeBSD.org
Mon Aug 4 23:00:15 UTC 2014


Author: brooks
Date: Mon Aug  4 23:00:13 2014
New Revision: 269541
URL: http://svnweb.freebsd.org/changeset/base/269541

Log:
  Merge from CheriBSD:
  
  Make the sysinit tool a build tool rather than building in with
  /usr/bin/cc and running it from OBJDIR.  (It will be moved to usr.bin
  once a manpage is written and a few style cleanups are done.)
  
  Split the makefile bits for Hans' kernel shim layer into their own
  includable kshim.mk.
  
  Move USB support into a .mk file so loaders can include it.

Added:
  head/sys/boot/kshim/
  head/sys/boot/kshim/bsd_busspace.c
     - copied unchanged from r269540, head/sys/boot/usb/bsd_busspace.c
  head/sys/boot/kshim/bsd_global.h
     - copied unchanged from r269521, head/sys/boot/usb/bsd_global.h
  head/sys/boot/kshim/bsd_kernel.c
     - copied unchanged from r269521, head/sys/boot/usb/bsd_kernel.c
  head/sys/boot/kshim/bsd_kernel.h
     - copied unchanged from r269521, head/sys/boot/usb/bsd_kernel.h
  head/sys/boot/kshim/kshim.mk
     - copied, changed from r269521, head/sys/boot/usb/Makefile
  head/sys/boot/kshim/sysinit.h
     - copied unchanged from r269521, head/sys/boot/usb/tools/sysinit.h
  head/sys/boot/usb/tools/Makefile   (contents, props changed)
  head/sys/boot/usb/usbcore.mk
     - copied, changed from r269521, head/sys/boot/usb/Makefile
Deleted:
  head/sys/boot/usb/bsd_busspace.c
  head/sys/boot/usb/bsd_global.h
  head/sys/boot/usb/bsd_kernel.c
  head/sys/boot/usb/bsd_kernel.h
  head/sys/boot/usb/tools/sysinit.h
Modified:
  head/Makefile.inc1
  head/sys/boot/usb/Makefile

Modified: head/Makefile.inc1
==============================================================================
--- head/Makefile.inc1	Mon Aug  4 22:37:02 2014	(r269540)
+++ head/Makefile.inc1	Mon Aug  4 23:00:13 2014	(r269541)
@@ -1406,7 +1406,8 @@ cross-tools: .MAKE
     usr.bin/xlint/lint1 usr.bin/xlint/lint2 usr.bin/xlint/xlint \
     ${_btxld} \
     ${_crunchide} \
-    ${_kgzip}
+    ${_kgzip} \
+    sys/boot/usb/tools
 	${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \
 		cd ${.CURDIR}/${_tool} && \
 		${MAKE} DIRPRFX=${_tool}/ obj && \

Copied: head/sys/boot/kshim/bsd_busspace.c (from r269540, head/sys/boot/usb/bsd_busspace.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/kshim/bsd_busspace.c	Mon Aug  4 23:00:13 2014	(r269541, copy of r269540, head/sys/boot/usb/bsd_busspace.c)
@@ -0,0 +1,207 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <bsd_kernel.h>
+
+struct burst {
+	uint32_t dw0;
+	uint32_t dw1;
+	uint32_t dw2;
+	uint32_t dw3;
+	uint32_t dw4;
+	uint32_t dw5;
+	uint32_t dw6;
+	uint32_t dw7;
+};
+
+void
+bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t *datap, bus_size_t count)
+{
+	while (count--) {
+		*datap++ = bus_space_read_1(t, h, offset);
+	}
+}
+
+void
+bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint16_t *datap, bus_size_t count)
+{
+	while (count--) {
+		*datap++ = bus_space_read_2(t, h, offset);
+	}
+}
+
+void
+bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t *datap, bus_size_t count)
+{
+	h += offset;
+
+	while (count--) {
+		*datap++ = *((volatile uint32_t *)h);
+	}
+}
+
+void
+bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t *datap, bus_size_t count)
+{
+	while (count--) {
+		uint8_t temp = *datap++;
+
+		bus_space_write_1(t, h, offset, temp);
+	}
+}
+
+void
+bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint16_t *datap, bus_size_t count)
+{
+	while (count--) {
+		uint16_t temp = *datap++;
+
+		bus_space_write_2(t, h, offset, temp);
+	}
+}
+
+void
+bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t *datap, bus_size_t count)
+{
+	h += offset;
+
+	while (count--) {
+		*((volatile uint32_t *)h) = *datap++;
+	}
+}
+
+void
+bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t data)
+{
+	*((volatile uint8_t *)(h + offset)) = data;
+}
+
+void
+bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint16_t data)
+{
+	*((volatile uint16_t *)(h + offset)) = data;
+}
+
+void
+bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t data)
+{
+	*((volatile uint32_t *)(h + offset)) = data;
+}
+
+uint8_t
+bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
+{
+	return (*((volatile uint8_t *)(h + offset)));
+}
+
+uint16_t
+bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
+{
+	return (*((volatile uint16_t *)(h + offset)));
+}
+
+uint32_t
+bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offset)
+{
+	return (*((volatile uint32_t *)(h + offset)));
+}
+
+void
+bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t *datap, bus_size_t count)
+{
+	h += offset;
+
+	while (count--) {
+		*datap++ = *((volatile uint8_t *)h);
+		h += 1;
+	}
+}
+
+void
+bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint8_t *datap, bus_size_t count)
+{
+	h += offset;
+
+	while (count--) {
+		*((volatile uint8_t *)h) = *datap++;
+		h += 1;
+	}
+}
+
+void
+bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t *datap, bus_size_t count)
+{
+	enum { BURST = sizeof(struct burst) / 4 };
+
+	h += offset;
+
+	while (count >= BURST) {
+		*(struct burst *)datap = *((/* volatile */ struct burst *)h);
+
+		h += BURST * 4;
+		datap += BURST;
+		count -= BURST;
+	}
+
+	while (count--) {
+		*datap++ = *((volatile uint32_t *)h);
+		h += 4;
+	}
+}
+
+void
+bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h,
+    bus_size_t offset, uint32_t *datap, bus_size_t count)
+{
+	enum { BURST = sizeof(struct burst) / 4 };
+
+	h += offset;
+
+	while (count >= BURST) {
+		*((/* volatile */ struct burst *)h) = *(struct burst *)datap;
+
+		h += BURST * 4;
+		datap += BURST;
+		count -= BURST;
+	}
+
+	while (count--) {
+		*((volatile uint32_t *)h) = *datap++;
+		h += 4;
+	}
+}

Copied: head/sys/boot/kshim/bsd_global.h (from r269521, head/sys/boot/usb/bsd_global.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/kshim/bsd_global.h	Mon Aug  4 23:00:13 2014	(r269541, copy of r269521, head/sys/boot/usb/bsd_global.h)
@@ -0,0 +1,65 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _BSD_GLOBAL_H_
+#define	_BSD_GLOBAL_H_
+
+#include <bsd_kernel.h>
+
+#define	USB_DEBUG_VAR usb_debug
+#include <dev/usb/usb_freebsd_loader.h>
+#include <dev/usb/usb_endian.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_core.h>
+#include <dev/usb/usb_debug.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usb_busdma.h>
+#include <dev/usb/usb_dynamic.h>
+#include <dev/usb/usb_transfer.h>
+#include <dev/usb/usb_device.h>
+#include <dev/usb/usb_hub.h>
+#include <dev/usb/usb_controller.h>
+#include <dev/usb/usb_bus.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usb_cdc.h>
+#include <dev/usb/usb_dev.h>
+#include <dev/usb/usb_mbuf.h>
+#include <dev/usb/usb_msctest.h>
+#include <dev/usb/usb_pci.h>
+#include <dev/usb/usb_pf.h>
+#include <dev/usb/usb_request.h>
+#include <dev/usb/usb_util.h>
+#include <dev/usb/usb_compat_linux.h>
+#include <dev/usb/usbhid.h>
+#include <dev/usb/usb_ioctl.h>
+#include <dev/usb/usb_generic.h>
+#include <dev/usb/quirk/usb_quirk.h>
+#include <dev/usb/template/usb_template.h>
+
+extern struct usb_process usb_process[USB_PROC_MAX];
+
+#endif					/* _BSD_GLOBAL_H_ */

Copied: head/sys/boot/kshim/bsd_kernel.c (from r269521, head/sys/boot/usb/bsd_kernel.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/boot/kshim/bsd_kernel.c	Mon Aug  4 23:00:13 2014	(r269541, copy of r269521, head/sys/boot/usb/bsd_kernel.c)
@@ -0,0 +1,1239 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2013 Hans Petter Selasky. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <bsd_global.h>
+
+struct usb_process usb_process[USB_PROC_MAX];
+
+static device_t usb_pci_root;
+
+/*------------------------------------------------------------------------*
+ * Implementation of mutex API
+ *------------------------------------------------------------------------*/
+
+struct mtx Giant;
+
+static void
+mtx_system_init(void *arg)
+{
+	mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE);
+}
+SYSINIT(mtx_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, mtx_system_init, NULL);
+
+void
+mtx_init(struct mtx *mtx, const char *name, const char *type, int opt)
+{
+	mtx->owned = 0;
+	mtx->parent = mtx;
+}
+
+void
+mtx_lock(struct mtx *mtx)
+{
+	mtx = mtx->parent;
+	mtx->owned++;
+}
+
+void
+mtx_unlock(struct mtx *mtx)
+{
+	mtx = mtx->parent;
+	mtx->owned--;
+}
+
+int
+mtx_owned(struct mtx *mtx)
+{
+	mtx = mtx->parent;
+	return (mtx->owned != 0);
+}
+
+void
+mtx_destroy(struct mtx *mtx)
+{
+	/* NOP */
+}
+
+/*------------------------------------------------------------------------*
+ * Implementation of shared/exclusive mutex API
+ *------------------------------------------------------------------------*/
+
+void
+sx_init_flags(struct sx *sx, const char *name, int flags)
+{
+	sx->owned = 0;
+}
+
+void
+sx_destroy(struct sx *sx)
+{
+	/* NOP */
+}
+
+void
+sx_xlock(struct sx *sx)
+{
+	sx->owned++;
+}
+
+void
+sx_xunlock(struct sx *sx)
+{
+	sx->owned--;
+}
+
+int
+sx_xlocked(struct sx *sx)
+{
+	return (sx->owned != 0);
+}
+
+/*------------------------------------------------------------------------*
+ * Implementaiton of condition variable API
+ *------------------------------------------------------------------------*/
+
+void
+cv_init(struct cv *cv, const char *desc)
+{
+	cv->sleeping = 0;
+}
+
+void
+cv_destroy(struct cv *cv)
+{
+	/* NOP */
+}
+
+void
+cv_wait(struct cv *cv, struct mtx *mtx)
+{
+	cv_timedwait(cv, mtx, -1);
+}
+
+int
+cv_timedwait(struct cv *cv, struct mtx *mtx, int timo)
+{
+	int start = ticks;
+	int delta;
+
+	if (cv->sleeping)
+		return (EWOULDBLOCK);	/* not allowed */
+
+	cv->sleeping = 1;
+
+	while (cv->sleeping) {
+		if (timo >= 0) {
+			delta = ticks - start;
+			if (delta >= timo || delta < 0)
+				break;
+		}
+		mtx_unlock(mtx);
+
+		usb_idle();
+
+		mtx_lock(mtx);
+	}
+
+	if (cv->sleeping) {
+		cv->sleeping = 0;
+		return (EWOULDBLOCK);	/* not allowed */
+	}
+	return (0);
+}
+
+void
+cv_signal(struct cv *cv)
+{
+	cv->sleeping = 0;
+}
+
+void
+cv_broadcast(struct cv *cv)
+{
+	cv->sleeping = 0;
+}
+
+/*------------------------------------------------------------------------*
+ * Implementation of callout API
+ *------------------------------------------------------------------------*/
+
+static void callout_proc_msg(struct usb_proc_msg *);
+
+volatile int ticks = 0;
+
+static LIST_HEAD(, callout) head_callout = LIST_HEAD_INITIALIZER(&head_callout);
+
+static struct mtx mtx_callout;
+static struct usb_proc_msg callout_msg[2];
+
+static void
+callout_system_init(void *arg)
+{
+	mtx_init(&mtx_callout, "callout-mtx", NULL, MTX_DEF | MTX_RECURSE);
+
+	callout_msg[0].pm_callback = &callout_proc_msg;
+	callout_msg[1].pm_callback = &callout_proc_msg;
+}
+SYSINIT(callout_system_init, SI_SUB_LOCK, SI_ORDER_MIDDLE, callout_system_init, NULL);
+
+static void
+callout_callback(struct callout *c)
+{
+	mtx_lock(c->mtx);
+
+	mtx_lock(&mtx_callout);
+	if (c->entry.le_prev != NULL) {
+		LIST_REMOVE(c, entry);
+		c->entry.le_prev = NULL;
+	}
+	mtx_unlock(&mtx_callout);
+
+	if (c->func)
+		(c->func) (c->arg);
+
+	if (!(c->flags & CALLOUT_RETURNUNLOCKED))
+		mtx_unlock(c->mtx);
+}
+
+void
+callout_process(int timeout)
+{
+	ticks += timeout;
+	usb_proc_msignal(usb_process + 2, &callout_msg[0], &callout_msg[1]);
+}
+
+static void
+callout_proc_msg(struct usb_proc_msg *pmsg)
+{
+	struct callout *c;
+	int delta;
+
+repeat:
+	mtx_lock(&mtx_callout);
+
+	LIST_FOREACH(c, &head_callout, entry) {
+
+		delta = c->timeout - ticks;
+		if (delta < 0) {
+			mtx_unlock(&mtx_callout);
+
+			callout_callback(c);
+
+			goto repeat;
+		}
+	}
+	mtx_unlock(&mtx_callout);
+}
+
+void
+callout_init_mtx(struct callout *c, struct mtx *mtx, int flags)
+{
+	memset(c, 0, sizeof(*c));
+
+	if (mtx == NULL)
+		mtx = &Giant;
+
+	c->mtx = mtx;
+	c->flags = (flags & CALLOUT_RETURNUNLOCKED);
+}
+
+void
+callout_reset(struct callout *c, int to_ticks,
+    void (*func) (void *), void *arg)
+{
+	callout_stop(c);
+
+	c->func = func;
+	c->arg = arg;
+	c->timeout = ticks + to_ticks;
+
+	mtx_lock(&mtx_callout);
+	LIST_INSERT_HEAD(&head_callout, c, entry);
+	mtx_unlock(&mtx_callout);
+}
+
+void
+callout_stop(struct callout *c)
+{
+	mtx_lock(&mtx_callout);
+
+	if (c->entry.le_prev != NULL) {
+		LIST_REMOVE(c, entry);
+		c->entry.le_prev = NULL;
+	}
+	mtx_unlock(&mtx_callout);
+
+	c->func = NULL;
+	c->arg = NULL;
+}
+
+void
+callout_drain(struct callout *c)
+{
+	if (c->mtx == NULL)
+		return;			/* not initialised */
+
+	mtx_lock(c->mtx);
+	callout_stop(c);
+	mtx_unlock(c->mtx);
+}
+
+int
+callout_pending(struct callout *c)
+{
+	int retval;
+
+	mtx_lock(&mtx_callout);
+	retval = (c->entry.le_prev != NULL);
+	mtx_unlock(&mtx_callout);
+
+	return (retval);
+}
+
+/*------------------------------------------------------------------------*
+ * Implementation of device API
+ *------------------------------------------------------------------------*/
+
+static const char unknown_string[] = { "unknown" };
+
+static TAILQ_HEAD(, module_data) module_head =
+    TAILQ_HEAD_INITIALIZER(module_head);
+
+static uint8_t
+devclass_equal(const char *a, const char *b)
+{
+	char ta, tb;
+
+	if (a == b)
+		return (1);
+
+	while (1) {
+		ta = *a;
+		tb = *b;
+		if (ta != tb)
+			return (0);
+		if (ta == 0)
+			break;
+		a++;
+		b++;
+	}
+	return (1);
+}
+
+int
+bus_generic_resume(device_t dev)
+{
+	return (0);
+}
+
+int
+bus_generic_shutdown(device_t dev)
+{
+	return (0);
+}
+
+int
+bus_generic_suspend(device_t dev)
+{
+	return (0);
+}
+
+int
+bus_generic_print_child(device_t dev, device_t child)
+{
+	return (0);
+}
+
+void
+bus_generic_driver_added(device_t dev, driver_t *driver)
+{
+	return;
+}
+
+device_t
+device_get_parent(device_t dev)
+{
+	return (dev ? dev->dev_parent : NULL);
+}
+
+void
+device_set_interrupt(device_t dev, driver_filter_t *filter,
+    driver_intr_t *fn, void *arg)
+{
+	dev->dev_irq_filter = filter;
+	dev->dev_irq_fn = fn;
+	dev->dev_irq_arg = arg;
+}
+
+void
+device_run_interrupts(device_t parent)
+{
+	device_t child;
+
+	if (parent == NULL)
+		return;
+
+	TAILQ_FOREACH(child, &parent->dev_children, dev_link) {
+		int status;
+		if (child->dev_irq_filter != NULL)
+			status = child->dev_irq_filter(child->dev_irq_arg);
+		else
+			status = FILTER_SCHEDULE_THREAD;
+
+		if (status == FILTER_SCHEDULE_THREAD) {
+			if (child->dev_irq_fn != NULL)
+				(child->dev_irq_fn) (child->dev_irq_arg);
+		}
+	}
+}
+
+void
+device_set_ivars(device_t dev, void *ivars)
+{
+	dev->dev_aux = ivars;
+}
+
+void   *
+device_get_ivars(device_t dev)
+{
+	return (dev ? dev->dev_aux : NULL);
+}
+
+int
+device_get_unit(device_t dev)
+{
+	return (dev ? dev->dev_unit : 0);
+}
+
+int
+bus_generic_detach(device_t dev)
+{
+	device_t child;
+	int error;
+
+	if (!dev->dev_attached)
+		return (EBUSY);
+
+	TAILQ_FOREACH(child, &dev->dev_children, dev_link) {
+		if ((error = device_detach(child)) != 0)
+			return (error);
+	}
+	return (0);
+}
+
+const char *
+device_get_nameunit(device_t dev)
+{
+	if (dev && dev->dev_nameunit[0])
+		return (dev->dev_nameunit);
+
+	return (unknown_string);
+}
+
+static uint8_t
+devclass_create(devclass_t *dc_pp)
+{
+	if (dc_pp == NULL) {
+		return (1);
+	}
+	if (dc_pp[0] == NULL) {
+		dc_pp[0] = malloc(sizeof(**(dc_pp)),
+		    M_DEVBUF, M_WAITOK | M_ZERO);
+
+		if (dc_pp[0] == NULL) {
+			return (1);
+		}
+	}
+	return (0);
+}
+
+static const struct module_data *
+devclass_find_create(const char *classname)
+{
+	const struct module_data *mod;
+
+	TAILQ_FOREACH(mod, &module_head, entry) {
+		if (devclass_equal(mod->mod_name, classname)) {
+			if (devclass_create(mod->devclass_pp)) {
+				continue;
+			}
+			return (mod);
+		}
+	}
+	return (NULL);
+}
+
+static uint8_t
+devclass_add_device(const struct module_data *mod, device_t dev)
+{
+	device_t *pp_dev;
+	device_t *end;
+	uint8_t unit;
+
+	pp_dev = mod->devclass_pp[0]->dev_list;
+	end = pp_dev + DEVCLASS_MAXUNIT;
+	unit = 0;
+
+	while (pp_dev != end) {
+		if (*pp_dev == NULL) {
+			*pp_dev = dev;
+			dev->dev_unit = unit;
+			dev->dev_module = mod;
+			snprintf(dev->dev_nameunit,
+			    sizeof(dev->dev_nameunit),
+			    "%s%d", device_get_name(dev), unit);
+			return (0);
+		}
+		pp_dev++;
+		unit++;
+	}
+	DPRINTF("Could not add device to devclass.\n");
+	return (1);
+}
+
+static void
+devclass_delete_device(const struct module_data *mod, device_t dev)
+{
+	if (mod == NULL) {
+		return;
+	}
+	mod->devclass_pp[0]->dev_list[dev->dev_unit] = NULL;
+	dev->dev_module = NULL;
+}
+
+static device_t
+make_device(device_t parent, const char *name)
+{
+	device_t dev = NULL;
+	const struct module_data *mod = NULL;
+
+	if (name) {
+
+		mod = devclass_find_create(name);
+
+		if (!mod) {
+
+			DPRINTF("%s:%d:%s: can't find device "
+			    "class %s\n", __FILE__, __LINE__,
+			    __FUNCTION__, name);
+
+			goto done;
+		}
+	}
+	dev = malloc(sizeof(*dev),
+	    M_DEVBUF, M_WAITOK | M_ZERO);
+
+	if (dev == NULL)
+		goto done;
+
+	dev->dev_parent = parent;
+	TAILQ_INIT(&dev->dev_children);
+
+	if (name) {
+		dev->dev_fixed_class = 1;
+		if (devclass_add_device(mod, dev)) {
+			goto error;
+		}
+	}
+done:
+	return (dev);
+
+error:
+	if (dev) {
+		free(dev, M_DEVBUF);
+	}
+	return (NULL);
+}
+
+device_t
+device_add_child(device_t dev, const char *name, int unit)
+{
+	device_t child;
+
+	if (unit != -1) {
+		device_printf(dev, "Unit is not -1\n");
+	}
+	child = make_device(dev, name);
+	if (child == NULL) {
+		device_printf(dev, "Could not add child '%s'\n", name);
+		goto done;
+	}
+	if (dev == NULL) {
+		/* no parent */
+		goto done;
+	}
+	TAILQ_INSERT_TAIL(&dev->dev_children, child, dev_link);
+done:
+	return (child);
+}
+
+int
+device_delete_child(device_t dev, device_t child)
+{
+	int error = 0;
+	device_t grandchild;
+
+	/* remove children first */
+
+	while ((grandchild = TAILQ_FIRST(&child->dev_children))) {
+		error = device_delete_child(child, grandchild);
+		if (error) {
+			device_printf(dev, "Error deleting child!\n");
+			goto done;
+		}
+	}
+
+	error = device_detach(child);
+
+	if (error)
+		goto done;
+
+	devclass_delete_device(child->dev_module, child);
+
+	if (dev != NULL) {
+		/* remove child from parent */
+		TAILQ_REMOVE(&dev->dev_children, child, dev_link);
+	}
+	free(child, M_DEVBUF);
+
+done:
+	return (error);
+}
+
+int
+device_delete_children(device_t dev)
+{
+	device_t child;
+	int error = 0;
+
+	while ((child = TAILQ_FIRST(&dev->dev_children))) {
+		error = device_delete_child(dev, child);
+		if (error) {
+			device_printf(dev, "Error deleting child!\n");
+			break;
+		}
+	}
+	return (error);
+}
+
+void
+device_quiet(device_t dev)
+{
+	dev->dev_quiet = 1;
+}
+
+const char *
+device_get_desc(device_t dev)
+{
+	if (dev)
+		return &(dev->dev_desc[0]);
+	return (unknown_string);
+}
+
+static int
+default_method(void)
+{
+	/* do nothing */
+	DPRINTF("Default method called\n");
+	return (0);
+}
+
+void   *
+device_get_method(device_t dev, const char *what)
+{
+	const struct device_method *mtod;
+
+	mtod = dev->dev_module->driver->methods;
+	while (mtod->func != NULL) {
+		if (devclass_equal(mtod->desc, what)) {
+			return (mtod->func);
+		}
+		mtod++;
+	}
+	return ((void *)&default_method);
+}
+
+const char *
+device_get_name(device_t dev)
+{
+	if (dev == NULL)
+		return (unknown_string);
+
+	return (dev->dev_module->driver->name);
+}
+
+static int
+device_allocate_softc(device_t dev)
+{
+	const struct module_data *mod;
+
+	mod = dev->dev_module;
+
+	if ((dev->dev_softc_alloc == 0) &&
+	    (mod->driver->size != 0)) {
+		dev->dev_sc = malloc(mod->driver->size,
+		    M_DEVBUF, M_WAITOK | M_ZERO);
+
+		if (dev->dev_sc == NULL)
+			return (ENOMEM);
+
+		dev->dev_softc_alloc = 1;
+	}
+	return (0);
+}
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list