+bool
+IOInterruptEventSource::init(OSObject *inOwner,
+ Action inAction,
+ IOService *inProvider,
+ int inIntIndex)
+{
+ bool res = true;
+
+ if (!super::init(inOwner, (IOEventSourceAction) inAction)) {
+ return false;
+ }
+
+ reserved = IONew(ExpansionData, 1);
+
+ if (!reserved) {
+ return false;
+ }
+
+ bzero(reserved, sizeof(ExpansionData));
+
+ provider = inProvider;
+ producerCount = consumerCount = 0;
+ autoDisable = explicitDisable = false;
+ intIndex = ~inIntIndex;
+
+ // Assumes inOwner holds a reference(retain) on the provider
+ if (inProvider) {
+ if (IA_ANY_STATISTICS_ENABLED) {
+ /*
+ * We only treat this as an "interrupt" if it has a provider; if it does,
+ * set up the objects necessary to track interrupt statistics. Interrupt
+ * event sources without providers are most likely being used as simple
+ * event source in order to poke at workloops and kick off work.
+ *
+ * We also avoid try to avoid interrupt accounting overhead if none of
+ * the statistics are enabled.
+ */
+ reserved->statistics = IONew(IOInterruptAccountingData, 1);
+
+ if (!reserved->statistics) {
+ /*
+ * We rely on the free() routine to clean up after us if init fails
+ * midway.
+ */
+ return false;
+ }
+
+ bzero(reserved->statistics, sizeof(IOInterruptAccountingData));
+
+ reserved->statistics->owner = this;
+ }
+
+ res = (kIOReturnSuccess == registerInterruptHandler(inProvider, inIntIndex));
+
+ if (res) {
+ intIndex = inIntIndex;
+ }
+ }
+
+ IOStatisticsInitializeCounter();
+
+ return res;
+}
+
+IOReturn
+IOInterruptEventSource::registerInterruptHandler(IOService *inProvider,
+ int inIntIndex)