/* * Selector channel scheduling routines */ #include "../h/local.h" #ifdef SCCS_ID static char SCCS_ID [] = "%Z%%M% %I% %Y% %U% - %E% "; #endif SCCS_ID #include "../h/param.h" #include "../h/buf.h" #include "../new/xselch.h" #undef trace extern char devmap[]; /* map device address => minor device no */ /* * Queue of devices using each selch * - top of queue is currently active device; others are waiting * * selchtab is indexed by the selch minor device number. * This should be generated by mkconf so it can have the * exact number of entries for the number of selches in the machine. * As it is, we assume that there will be no more than 8 selches. */ struct xselchtab { struct xselchq *sc_actf; struct xselchq *sc_actl; } xselchtab[8]; /* * Request use of xselch with address n */ xselchreq(n, xselchq, unit) struct xselchq *xselchq; int unit; { register struct xselchq *s; register struct xselchtab *st; register free; trace(2<<16, "xschrequest", xselchq); st = &xselchtab[devmap[n]]; /* Make sure request not already on queue */ for (s = st->sc_actf; s; s = s->sq_forw) if (s == xselchq) return; (s = xselchq)->sq_forw = 0; s->sq_unitno = unit; if (st->sc_actf) { st->sc_actl->sq_forw = s; free = 0; } else { st->sc_actf = s; free = 1; } st->sc_actl = s; if (free){ (*s->sq_sstart)(s->sq_unitno); return(0); } else { return(1); } } /* * Free xselch with address n for next device */ xselchfree(n) { register struct xselchq *s; register struct xselchtab *st; st = &xselchtab[devmap[n]]; trace(2<<16, "xschfree", st->sc_actf); if ((s = st->sc_actf) == 0) return; st->sc_actf = s = s->sq_forw; if (s) (*s->sq_sstart)(s->sq_unitno); } /* * Selector channel interrupt -- handled by currently active device */ xselchintr(dev, stat) { register struct xselchq *s; register struct xselchtab *st; trace(4<<16, "xschint", dev); trace(4<<16, "xstatus", stat); st = &xselchtab[dev]; if (s = st->sc_actf) (*s->sq_sintr)(dev, stat, s->sq_unitno); }