> > Somebody should fix the driver so that zshard() does not call > > device_lookup_private(). It seems entirely unnecessary. > > There is a dumb hack in sun3 derived zs driver. > > All zs devices on sun machines have the same interrupt sources > so ancient zs drivers tried to reduce overhead on interrupts > by sharing one interrupt handler among all zs devices. > > We can simpley fix it to make it call softint_establish() and > bus_intr_establish() per each zs device, as macppc and news68k etc. do.
i don't understand. the macppc and news68k zshard()'s get the actual zsc_softc * as the (void *arg), but sparc does not. seems like the only way to deal with this is to keep a local copy of the zsc structures some how and to traverse this inside of zshard(). i probably should have used queue.h but i finished this patch before i considered it... my ss20 has booted just fine with this patch but it wasn't failing before either. .mrg. Index: include/z8530var.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/include/z8530var.h,v retrieving revision 1.9 diff -p -r1.9 z8530var.h *** include/z8530var.h 29 Mar 2008 19:15:35 -0000 1.9 --- include/z8530var.h 20 Jun 2010 01:34:29 -0000 *************** struct zsc_softc { *** 54,59 **** --- 54,65 ---- int zsc_node; /* PROM node, if any */ struct evcnt zsc_intrcnt; /* count interrupts */ struct zs_chanstate zsc_cs_store[2]; + + /* + * This is used for zshard() to avoid having to call + * device_lookup_private() from IPL_HIGH. + */ + struct zsc_softc *zsc_next; }; /* Index: dev/zs.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/dev/zs.c,v retrieving revision 1.118 diff -p -r1.118 zs.c *** dev/zs.c 4 Jun 2010 06:04:15 -0000 1.118 --- dev/zs.c 20 Jun 2010 01:34:29 -0000 *************** extern struct cfdriver zs_cd; *** 174,179 **** --- 174,182 ---- /* softintr(9) cookie, shared by all instances of this driver */ static void *zs_sicookie; + /* Linked list of zs instances, for fast lookups in zshard */ + static struct zsc_softc *zsc_first; + /* Interrupt handlers. */ static int zshard(void *); static void zssoft(void *); *************** zs_attach(struct zsc_softc *zsc, struct *** 566,571 **** --- 569,580 ---- } /* + * Install this zs into the zshard fast lookup list. + */ + zsc->zsc_next = zsc_first; + zsc_first = zsc; + + /* * Now safe to install interrupt handlers. Note the arguments * to the interrupt handlers aren't used. Note, we only do this * once since both SCCs interrupt at the same level and vector. *************** static int *** 632,646 **** zshard(void *arg) { struct zsc_softc *zsc; ! int unit, rr3, rval, softreq; rval = softreq = 0; ! for (unit = 0; unit < zs_cd.cd_ndevs; unit++) { struct zs_chanstate *cs; - zsc = device_lookup_private(&zs_cd, unit); - if (zsc == NULL) - continue; rr3 = zsc_intr_hard(zsc); /* Count up the interrupts. */ if (rr3) { --- 641,652 ---- zshard(void *arg) { struct zsc_softc *zsc; ! int rr3, rval, softreq; rval = softreq = 0; ! for (zsc = zsc_first; zsc; zsc = zsc->zsc_next) { struct zs_chanstate *cs; rr3 = zsc_intr_hard(zsc); /* Count up the interrupts. */ if (rr3) {