Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Dec 2007 16:16:07 GMT
From:      Maxim Zhuravlev <thioretic@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 131706 for review
Message-ID:  <200712261616.lBQGG7FV018666@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=131706

Change 131706 by thioretic@thioretic on 2007/12/26 16:16:02

	The event framework is now well outlined. It's not extensible yet.
		Still, the extensibility is implied by design.

Affected files ...

.. //depot/projects/soc2007/thioretic_gidl2/kern/device_if.m#3 edit
.. //depot/projects/soc2007/thioretic_gidl2/kern/subr_bus.c#11 edit
.. //depot/projects/soc2007/thioretic_gidl2/sys/bus.h#7 edit

Differences ...

==== //depot/projects/soc2007/thioretic_gidl2/kern/device_if.m#3 (text+ko) ====

@@ -67,7 +67,7 @@
 		return NULL;
 	}
 	static void null_receive_event (device_t dev, device_t provider, 
-			enum relationship rel, enum dev_event ev)
+			int rel, uint32_t ev)
 	{
 		return;
 	}
@@ -375,6 +375,6 @@
 METHOD void receive_event {
 	device_t dev;
 	device_t provider;
-	enum relationship	rel;
-	enum dev_event ev_type;
+	int	rel;
+	uint32_t ev_type;
 } DEFAULT null_receive_event;
==== //depot/projects/soc2007/thioretic_gidl2/kern/subr_bus.c#11 (text+ko) ====

@@ -130,7 +130,7 @@
 };
 
 struct dev_event_entry {
-	enum dev_event ev_type;
+	uint32_t ev_type;
 	TAILQ_ENTRY(dev_event_entry) link;
 };
 typedef struct dev_event_entry* dev_event_entry_t;
@@ -2069,24 +2069,42 @@
 	}
 }
 
-static void device_issue_event (device_t dev, enum dev_event ev_type){
+static void device_issue_event (device_t dev, uint32_t ev_type){
 	dev_event_entry_t dee;
 	devicelink_t pd;
+	int dequeuedevents = 0;
+
+	if (ev_type > EV_MAX)
+		return;
 
 	/*deliver to all children*/
-	if (!TAILQ_EMPTY(&dev->children)){
+	if ((event_pref[ev_type] & REL_CHILD) &&
+		!TAILQ_EMPTY(&dev->children)){
 		TAILQ_FOREACH (pd, &dev->children, link){
-			DEVICE_RECEIVE_EVENT (pd, dev, REL_CHILD, ev_type);
+			DEVICE_RECEIVE_EVENT (pd, dev, REL_PARENT, ev_type);
 		}
 	}
 
 	/*deliver to all parents*/
-	if (!TAILQ_EMPTY(&dev->parents)){
+	if ((event_pref[ev_type] & REL_PARENT) &&
+		!TAILQ_EMPTY(&dev->parents)){
 		TAILQ_FOREACH (pd, &dev->parents, link){
-			DEVICE_RECEIVE_EVENT (pd, dev, REL_PARENT, ev_type);
+			DEVICE_RECEIVE_EVENT (pd, dev, REL_CHILD, ev_type);
 		}
 	}
 
+	while (!TAILQ_EMPTY(&dev->evs)){
+		dee = TAILQ_LAST(&dev->evs, dev_event_list);
+		if (!(event_pref[ev_type] & (1<<(dee->ev_type))))
+			break;
+		TAILQ_REMOVE(&dev->evs, dee, link);
+		free (dee);
+		dequeuedevents++;
+	}
+
+	if (dequeuedevents > 0 && !(event_pref[ev_type] & EVP_ENQALWAYS))
+		return;
+
 	/*enqueue*/
 	dee = malloc (sizeof(struct dev_event_entry), M_BUS, M_NOWAIT|M_ZERO);
 	if (dee == NULL)
@@ -2096,7 +2114,7 @@
 	TAILQ_INSERT_TAIL (&dev->evs, dee, link);
 }
 
-static void device_deliver_events (device_t dev, device_t recipient, enum relationship rel){
+static void device_deliver_events (device_t dev, device_t recipient, int rel){
 	dev_event_entry_t dee;
 	
 	if (TAILQ_EMPTY(&dev->evs))
@@ -3299,6 +3317,11 @@
 	if(driver == NULL || level == DRL_LOWEST){
 		if(!device_destroy_configuration(dev))
 			return (EBUSY);
+		while (!TAILQ_EMPTY(&dev->evs)){
+			dee = TAILQ_FIRST(&dev->evs);
+			TAILQ_REMOVE (&dev->evs, dee, link);
+			free (dee);
+		}
 	}
 
 	if (!dil){
@@ -3444,6 +3467,7 @@
 		dev->driver_level=DRL_LOWEST;
 		return (error);
 	}
+	device_issue_event(dev, EV_ATTACH);
 
 	dil = dev->driver;
 	if (dev->driver_level == DRL_LOWEST){
@@ -3481,6 +3505,7 @@
 {
 	int error;
 	devicelink_t pd;
+	dev_event_entry_t dee;
 
 	GIANT_REQUIRED;
 
@@ -3492,6 +3517,7 @@
 
 	if ((error = DEVICE_DETACH(dev)) != 0)
 		return (error);
+	
 	if (dev->driver_level != DRL_LOWEST){
 		TAILQ_REMOVE(&dev->drivers[dev->driver_level], dev->driver, link);
 		free(dev->driver);
@@ -3503,6 +3529,8 @@
 			dev->state = DS_ATTACHED;
 		return (0);
 	}
+	device_issue_event(dev, EV_DETACH);
+
 	devremoved(dev);
 	device_printf(dev, "detached\n");
 	if (!TAILQ_EMPTY(&dev->parents)){
@@ -3538,6 +3566,7 @@
 int
 device_quiesce(device_t dev)
 {
+	int result;
 
 	PDEBUG(("%s", DEVICENAME(dev)));
 	if (dev->state == DS_BUSY)
@@ -3545,7 +3574,10 @@
 	if (dev->state != DS_ATTACHED)
 		return (0);
 
-	return (DEVICE_QUIESCE(dev));
+	if (result = DEVICE_QUIESCE(dev))
+		device_issue_event(dev, EV_QUIESCE);
+
+	return (result);
 }
 
 /**
@@ -3559,9 +3591,14 @@
 int
 device_shutdown(device_t dev)
 {
+	int result;
+
 	if (dev->state < DS_ATTACHED)
 		return (0);
-	return (DEVICE_SHUTDOWN(dev));
+	result = DEVICE_SHUTDOWN(dev);
+	device_issue_event(dev, EV_SHUTDOWN);
+
+	return (result);
 }
 
 /**
@@ -4033,10 +4070,13 @@
 		if (error) {
 			for (child2 = TAILQ_FIRST(&dev->children);
 			     child2 && child2 != child;
-			     child2 = TAILQ_NEXT(child2, link))
+				 child2 = TAILQ_NEXT(child2, link)){
 				DEVICE_RESUME(child2);
+//				device_issue_event(child2, EV_RESUME);
+			}
 			return (error);
 		}
+		device_issue_event(child, EV_SUSPEND);
 	}
 	return (0);
 }
@@ -4053,7 +4093,8 @@
 	device_t	child;
 
 	TAILQ_FOREACH(child, &dev->children, link) {
-		DEVICE_RESUME(child);
+		if (DEVICE_RESUME(child))
+			device_issue_event(child, EV_RESUME);
 		/* if resume fails, there's nothing we can usefully do... */
 	}
 	return (0);

==== //depot/projects/soc2007/thioretic_gidl2/sys/bus.h#7 (text+ko) ====

@@ -713,21 +713,35 @@
 	bus_space_write_region_stream_8(rman_get_bustag(r), rman_get_bushandle(r), (o), (d), (c))
 
 /**
- * Triggers support functions
+ * event support functions
+ */
+#define EV_ATTACH	0
+#define EV_DETACH	1
+#define EV_RESUME	2
+#define EV_SUSPEND	3
+#define EV_QUIESCE	4
+#define	EV_SHUTDOWN	5
+
+#define EV_MAX	28
+
+#define REL_CHILD	(1<<29)
+#define REL_PARENT	(1<<30)
+#define EVP_ENQALWAYS	(1<<31)
+/**
+ * event_pref array is an array of event settings.
+ * includes:
+ * what devices should receive the event (children and/or parents)
+ * what enqueued events should be dequeued
  */
-enum dev_event{
-	EV_ATTACH,
-	EV_DETACH,
-	EV_RESUME,
-	EV_SUSPEND,
-	EV_QUIESCE,
-	EV_SHUTDOWN
-};
 
-enum relationship {
-	REL_CHILD,
-	REL_PARENT
-};
+uint32_t event_pref[32] = 
+	{ REL_CHILD | REL_PARENT,	/* EV_ATTACH */
+	  REL_CHILD | REL_PARENT | (REL_CHILD - 1),	/* EV_DETACH */
+	  REL_CHILD | REL_PARENT | (1<<EV_SUSPEND),	/* EV_RESUME */
+	  REL_CHILD | REL_PARENT | (1<<EV_RESUME),	/* EV_SUSPEND */
+	  REL_CHILD | REL_PARENT,	/* EV_QUIESCE */	/* TODO */
+	  REL_CHILD | REL_PARENT,	/* EV_SHUTDOWN */	/* TODO */
+	};
 
 #endif /* _KERNEL */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712261616.lBQGG7FV018666>