/* Lookup a node in the name registry tree */ int NRFindNode( char *name, char *type, RegEntryID *node_id ) { Boolean done; RegEntryIter cookie; RegEntryID re; OSStatus status; unsigned long prop_size; char buf[32]; int found = 0; RegistryEntryIterateCreate( &cookie ); for( ; !found ; RegistryEntryIDDispose(&re) ) { status = RegistryEntryIterate( &cookie, kRegIterContinue, &re, &done ); if( done || status ) break; prop_size = sizeof(buf); if( name ) { status = RegistryPropertyGet( &re, "name", buf, &prop_size ); if( status || CStrNCmp( buf, name, sizeof(buf) ) ) continue; } if( type ) { status = RegistryPropertyGet( &re, "type", buf, &prop_size ); if( status || CStrNCmp( buf, name, sizeof(buf) ) ) continue; } RegistryEntryIDCopy( &re, node_id ); found = 1; } RegistryEntryIterateDispose( &cookie ); return found; }
OSStatus InstallIRQ( RegEntryID *reg_entry, InterruptHandler handler, IRQInfo *info ) { RegPropertyValueSize propertySize; OSStatus status; if( (status=ExtendISTTree(reg_entry)) ) return status; propertySize = sizeof(ISTProperty); if( (status=RegistryPropertyGet( reg_entry, kISTPropertyName, &info->istp, &propertySize)) ) { lprintf("Could not find the 'driver-ist' node (status %d)!\n", status); return status; } propertySize = sizeof(info->aapl_int); if( RegistryPropertyGet( reg_entry, "AAPL,interrupts", &info->aapl_int, &propertySize ) ) info->aapl_int = 0; info->interruptSetMember.setID = info->istp[kISTChipInterruptSource].setID; info->interruptSetMember.member = info->istp[kISTChipInterruptSource].member; status = GetInterruptFunctions( info->istp[kISTChipInterruptSource].setID, info->istp[kISTChipInterruptSource].member, &info->oldInterruptSetRefcon, &info->oldInterruptServiceFunction, &info->oldInterruptEnableFunction, &info->oldInterruptDisableFunction); if( status != noErr ) { lprintf("InstallIRQ, GetInterruptFunctions failed (%d)\n", status ); return status; } if( info->oldInterruptDisableFunction ) info->oldInterruptDisableFunction( info->istp[kISTChipInterruptSource], info->oldInterruptSetRefcon); status = InstallInterruptFunctions( info->istp[kISTChipInterruptSource].setID, info->istp[kISTChipInterruptSource].member, NULL, handler, NULL, NULL ); if( status != noErr ) { lprintf("InstallIRQ, InstallInterruptFunctions failed (%d)\n", status ); return status; } propertySize = 4; if( (status=RegistryPropertyGet( reg_entry, "reg", &info->pci_addr, &propertySize )) ) { lprintf("Could not get the 'reg' property for the interrupt node\n"); return status; } /* enable interrupts */ if( info->oldInterruptEnableFunction ) info->oldInterruptEnableFunction( info->interruptSetMember, info->oldInterruptSetRefcon ); return status; }
OSErr XPFIODevice::getRegistryProperty (REG_ENTRY_TYPE entry, char *key, char *value) { value[0] = 0; #ifdef __MACH__ CFStringRef cfKey = CFStringCreateWithCString (NULL, key, kCFStringEncodingASCII); CFTypeRef cfValue = IORegistryEntryCreateCFProperty (entry, cfKey, NULL, 0); if (!cfValue) return -1; if (CFGetTypeID (cfValue) == CFDataGetTypeID ()) { memcpy (value, CFDataGetBytePtr ((CFDataRef) cfValue), CFDataGetLength ((CFDataRef) cfValue)); value [CFDataGetLength ((CFDataRef) cfValue)] = 0; CFRelease (cfValue); } return noErr; #else RegPropertyValueSize propSize; OSErr err = RegistryPropertyGetSize (entry, key, &propSize); if (err == noErr) { RegistryPropertyGet (entry, key, value, &propSize); value[propSize] = '\0'; } return err; #endif }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * GetDeviceInterruptPropertyInfo retrieves the interrupt-service property information * from the System Registry. If successful, it installs our primary interrupt service * routine (PCIInterruptServiceRoutine) */ OSStatus InstallISR(InterruptHandler handler) { OSStatus osStatus; RegPropertyValueSize propertySize; propertySize = sizeof(ISTProperty); osStatus = RegistryPropertyGet(&GLOBAL.deviceEntry, kISTPropertyName, &GLOBAL.theISTProperty, &propertySize); if (osStatus) { #if 1 lprintf("RegistryPropertyGet failed\n"); #endif return osStatus; } GLOBAL.interruptSetMember.setID = GLOBAL.theISTProperty[kISTChipInterruptSource].setID; GLOBAL.interruptSetMember.member = GLOBAL.theISTProperty[kISTChipInterruptSource].member; osStatus = GetInterruptFunctions(GLOBAL.theISTProperty[kISTChipInterruptSource].setID, GLOBAL.theISTProperty[kISTChipInterruptSource].member, &GLOBAL.oldInterruptSetRefcon, &GLOBAL.oldInterruptServiceFunction, &GLOBAL.oldInterruptEnableFunction, &GLOBAL.oldInterruptDisableFunction); if (osStatus == noErr) { osStatus = InstallInterruptFunctions(GLOBAL.theISTProperty[kISTChipInterruptSource].setID, GLOBAL.theISTProperty[kISTChipInterruptSource].member, NULL, handler, NULL, NULL); if (GLOBAL.oldInterruptDisableFunction) GLOBAL.oldInterruptDisableFunction(GLOBAL.theISTProperty[kISTChipInterruptSource], GLOBAL.oldInterruptSetRefcon); } return osStatus; }
static OSStatus ExtendISTTree( RegEntryID *reg_entry ) { enum { MAX_NUM_FUNCS = 8 }; RegPropertyValueSize propertySize; RegEntryID funcs[MAX_NUM_FUNCS], root_id, re; int i, found=0, num_funcs=0, num_roots=0; unsigned long reg1, reg2; RegEntryIter cookie; ISTProperty istp; OSStatus status; Boolean done; /* lprintf("ExtendISTTree\n"); */ /* Find out which devfn we are examining */ propertySize = 4; if( (status=RegistryPropertyGet( reg_entry, "reg", ®1, &propertySize)) ) { lprintf("Node is lacking a 'reg' property"); return -1; } /* Allocate IDs */ for( i=0; i<MAX_NUM_FUNCS; i++ ) RegistryEntryIDInit( &funcs[i] ); RegistryEntryIDInit( &root_id ); /* Find all nodes whith this bus and device number */ RegistryEntryIterateCreate( &cookie ); for( ;; RegistryEntryIDDispose(&re) ) { status = RegistryEntryIterate( &cookie, kRegIterContinue, &re, &done ); if( done || status != noErr ) break; propertySize = 4; if( RegistryPropertyGet( &re, "reg", ®2, &propertySize ) ) continue; /* Only the function number may different */ if( (reg2 & ~0x700) != (reg1 & ~0x700) ) continue; if( num_funcs >= MAX_NUM_FUNCS ) { lprintf("Too many cards found!\n"); continue; } RegistryEntryIDCopy( &re, &funcs[num_funcs++] ); propertySize = sizeof( ISTProperty ); if( !RegistryPropertyGet( &re, kISTPropertyName, &istp, &propertySize) ) { if( !num_roots++ ) RegistryEntryIDCopy( &re, &root_id ); } } RegistryEntryIterateDispose( &cookie ); status = noErr; if( !num_roots || !num_funcs ) { lprintf("Could not find the interrupt node (num_roots %d, num_funcs %d)!\n", num_roots, num_funcs); } else if( num_roots == 1 && num_funcs > 1 ) { status = DoExtendISTTree( &root_id, funcs, num_funcs, &istp ); } /* Free IDs */ for( i=0; i<MAX_NUM_FUNCS; i++ ) RegistryEntryIDDispose( &funcs[i] ); RegistryEntryIDDispose( &root_id ); if( status ) lprintf("Error %d in ExtendISTTree\n", status ); return status; }