/* * EvUnRegisterEventClass() removes an event class from the list * of known event classes. If this is a local event group then * it is removed only locally. If this is a member of an event * group then a notices is sent to the master to remove the event * class. If the master indicates it is OK then the class is removed * locally. * * If this is an event master and every thing is OK locally then * the event class is removes locally and the members are informed * to remove it also. */ int EvUnRegisterEventClass(EvGroupID_t groupID, EvClassID_t classID, EvAccess_t accessCode) { EvGroupInfo_t *EGroup; unsigned long Flags; int RetVal; /* Get the group info pointer and return with it locked. */ if ((RetVal = EvLockAndGetGroup(groupID, EV_ACCESS_IGNORE, EAC_NONE, &Flags, EV_LOCK_GROUP_WRITE, &EGroup))) { return RetVal; } /* If this is a Member send remove request to master. */ if (EGroup->EgiType == EG_MEMBER) { if ((RetVal = EvSendUnRegEventClass(EGroup, accessCode, classID, &Flags)) < 0) { write_unlock_irqrestore(&EGroup->EgiLock, Flags); return RetVal; } } RetVal = EvInternalUnRegisterEventClass(EGroup, classID, accessCode); write_unlock_irqrestore(&EGroup->EgiLock, Flags); return RetVal; }
/* * EvDeleteGroup() removes and event group from the system. This function * is not allowed to succed if there are event subscribers waiting on this * event group. First the local structures for the event group are removed. * Once this is done if this is an events. * * Looks like this still needs some work. */ int EvDeleteGroup(EvGroupID_t groupID, EvAccess_t accessCode) { EvGroupInfo_t *TmpGroup; EvGroupInfo_t *FreeGroup; unsigned long Flags; write_lock_irqsave(&EvGroupLock, Flags); if (EvGroupHead == NULL) { write_unlock_irqrestore(&EvGroupLock, Flags); return -EV_ERROR_GROUP_EXIST; } /* Check to see if this is at the head. If so this is the local * group and in not deletable. */ if (EvGroupHead->EgiID == groupID) { write_unlock_irqrestore(&EvGroupLock, Flags); return -EV_ERROR_GROUP_BUSY; } TmpGroup = EvGroupHead; while(TmpGroup->EgiNext) { if (TmpGroup->EgiNext->EgiID == groupID) { FreeGroup = TmpGroup->EgiNext; if (FreeGroup->EgiUseCount > 1) { /* For now just do not allow unregisteration. */ write_unlock_irqrestore(&EvGroupLock, Flags); return -EV_ERROR_GROUP_BUSY; } if (EvCheckAccessCode(FreeGroup->EgiAccessCode, accessCode)) { write_unlock_irqrestore(&EvGroupLock, Flags); return -EV_ERROR_GROUP_ACCESS; } EvInternalUnRegisterEventClass(FreeGroup, 0, EvGetClassAccess(FreeGroup, 0)); TmpGroup->EgiNext = FreeGroup->EgiNext; write_unlock_irqrestore(&EvGroupLock, Flags); kfree(FreeGroup->EgiClassHash); kfree(FreeGroup); return EV_NOERR; } TmpGroup = TmpGroup->EgiNext; } write_unlock_irqrestore(&EvGroupLock, Flags); return -EV_ERROR_GROUP_EXIST; }
int EvRemoteUnRegisterEventClass(EvGroupID_t groupID, EvClassID_t classID, EvAccess_t accessCode, int error) { EvGroupInfo_t *EGroup; EvPendRem_t *Pend; unsigned long Flags; int RetVal; read_lock_irqsave(&EvGroupLock, Flags); if ((EGroup = EvGetGroupBase(groupID)) == NULL) { read_unlock_irqrestore(&EvGroupLock, Flags); return -EV_ERROR_GROUP_EXIST; } write_lock(&EGroup->EgiLock); read_unlock(&EvGroupLock); /* Pend the pending control struct for this ID. * * If Pend is NULL then this is the master reporting a new event * class. */ if ((Pend = EvFindPendEntry(EGroup, EV_REM_UNREGISTER_EVENT_CLASS, accessCode, classID, 0, 0, 0, NULL)) != NULL) { /* Fill in the return values. */ Pend->PrRetInfo.EpInfo[0] = error; /* Wake up the requester. */ wake_up_interruptible(&Pend->PrWaitQ); write_unlock_irqrestore(&EGroup->EgiLock, Flags); return EV_NOERR; } RetVal = EvInternalUnRegisterEventClass(EGroup, classID, accessCode); write_unlock_irqrestore(&EGroup->EgiLock, Flags); return RetVal; }