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>