+
+ /* No goto finish from here to unlock.
+ */
+ IORWLockWrite(lock);
+
+ while ((key = (const OSSymbol *) iter->getNextObject()))
+ {
+ array = (OSArray *) personalities->getObject(key);
+ if (!array) continue;
+
+ for (idx = 0;
+ (thisOldPersonality = (OSDictionary *) array->getObject(idx));
+ idx++)
+ {
+ if (thisOldPersonality->getObject("KernelConfigTable")) continue;
+ thisNewPersonality = NULL;
+
+ if (newPersonalities) {
+ for (newIdx = 0;
+ (thisNewPersonality = (OSDictionary *) newPersonalities->getObject(newIdx));
+ newIdx++)
+ {
+ /* Unlike in other functions, this comparison must be exact!
+ * The catalogue must be able to contain personalities that
+ * are proper supersets of others.
+ * Do not compare just the properties present in one driver
+ * personality or the other.
+ */
+ if (OSDynamicCast(OSDictionary, thisNewPersonality) == NULL) {
+ /* skip thisNewPersonality if it is not an OSDictionary */
+ continue;
+ }
+ if (thisNewPersonality->isEqualTo(thisOldPersonality))
+ break;
+ }
+ }
+ if (thisNewPersonality) {
+ // dup, ignore
+ newPersonalities->removeObject(newIdx);
+ }
+ else {
+ // not in new set - remove
+ // only remove dictionary if this module in not loaded - 9953845
+ if ( isModuleLoadedNoOSKextLock(myKexts, thisOldPersonality) == false ) {
+ if (matchSet) {
+ matchSet->setObject(thisOldPersonality);
+ }
+ array->removeObject(idx);
+ idx--;
+ }
+ }
+ } // for...
+ } // while...
+
+ // add new
+ if (newPersonalities) {
+ for (newIdx = 0;
+ (thisNewPersonality = (OSDictionary *) newPersonalities->getObject(newIdx));
+ newIdx++)
+ {
+ if (OSDynamicCast(OSDictionary, thisNewPersonality) == NULL) {
+ /* skip thisNewPersonality if it is not an OSDictionary */
+ continue;
+ }
+
+ OSKext::uniquePersonalityProperties(thisNewPersonality);
+ addPersonality(thisNewPersonality);
+ matchSet->setObject(thisNewPersonality);
+ }
+ }
+
+ /* Finally, start device matching on all new & removed personalities.
+ */
+ if (result && doNubMatching && (matchSet->getCount() > 0)) {
+ IOService::catalogNewDrivers(matchSet);
+ generation++;
+ }
+
+ IORWLockUnlock(lock);
+
+finish:
+ if (matchSet) matchSet->release();
+ if (iter) iter->release();
+ if (myKexts) myKexts->release();
+
+ return result;