Path: news.mitre.org!blanket.mitre.org!philabs!newsjunkie.ans.net!newsfeeds.ans.net!news-was.dfn.de!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!news-peer.sprintlink.net!news-backup-west.sprintlink.net!news-in-west.sprintlink.net!news.sprintlink.net!Sprint!209.90.0.8!alpha.sky.net!newshub.cts.com!newsfeed.cts.com!cmkrnl!jeh From: jeh@cmkrnl.com (Jamie Hanrahan) Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode Subject: Re: Various beginner questions on DDKs Message-ID: <1998Jan14.161913.8410@cmkrnl> Date: 14 Jan 98 16:19:13 PST References: <69fmvs$b2v$1@smilodon.ecp.fr> Organization: Kernel Mode Systems, San Diego, CA Lines: 86 In article <69fmvs$b2v$1@smilodon.ecp.fr>, riad@cti.ecp.fr (El Gringo) writes: > 1- How to synchronize two different ISR ? (different DIRQL levels) This is fairly simple to set up. You need to have storage for a spinlock and for an a array of pointers to interrupt objects in your device extension (or somewhere else convenient). Then assuming that in irq[] you have the IRQs you want to connect to: // in the device extension typedef struct _MY_DVC_EXT { ... KSPIN_LOCK InterruptSpinLock; PKINTERRUPT_OBJECT IntObj[n]; } // allocate some temporaries KIRQL highIrql; KIRQL irql[nInts]; KAFFINITY affinity[nInts]; ULONG vec[nInts]; // initialize our spinlock KeInitializeSpinLock ( &dvcExt->InterruptSpinLock ); // do all the HalGetInterruptVector calls, saving the returned vectors, // dIRQLs, and affinities in arrays, and tracking the highest dIRQL highIrql = PASSIVE_LEVEL; for ( i = 0 ; i < nInts ; i++) { vec[i] = HalGetInterruptVector( Isa, 0, // whatever irq[i], // the input interrupt "level" (IRQ) irq[i], // the input interrupt "vector" (same as level for // PC buses) &irql[i], // the output IRQL &affinity[i]); // the output affinity mask if (irql[i] > highIrql) highIrql = irql[i]; } // now connect to all of the interrupts, passing the respective // IRQL, affinity, and vector. For SynchIrql, use the highest of // all of the IRQLs. For the spinlock argument, use the // driver-supplied spinlock. This way, all interrupt objects // have the same SynchIrql, and all point to the same spinlock. for ( i = 0 ; i < nInts ; i++) { IoConnectInterrupt ( &dvcExt->IntObj[i], // save the returned interrupt object addresses MyIsr, // you could use a different ISR entry point for each interrupt dvcObj, // likewise, you could use a different ISR context for each interrupt &dvcExt->InterruptSpinLock, // common interrupt object spinlock for all of our interrupts vec[i], // the vector for this interrupt irql[i], // the IRQL for this interrupt highIrql, // the highest of all our interrupts' IRQLs interruptMode, // as appropriate shareVector, // as appropriate affinity[i], // the affinity mask for this interrupt floatingSave); // as appropriate } Then: All of the ISRs for all of the interrupts will be serialized with respect to each other, and also with respect to any SynchCritSection routines invoked via KeSynchronizeExecution used with ANY of the returned interrupt objects. Source: KMD Design Guide, section 3.5.2 and 8.1.3, plus a bit of intuition and reading between the lines. Note, don't pass &dvcExt->InterruptObjectSpinlock to KeAcquireSpinLock! --- Jamie Hanrahan, Kernel Mode Systems, San Diego CA Internet: jeh@cmkrnl.com (JH645) CompuServe: 74140,2055 drivers, internals, networks, applications, and training for VMS and Windows NT NT driver FAQ, links, and other information: http://www.cmkrnl.com/ If you post a reply in news, please don't e-mail it too.