Пример #1
0
int
EvSetClassAccessCode(EvGroupID_t groupID, EvClassID_t classID,
		     EvAccess_t oldCode, EvAccess_t newCode)
{
	EvGroupInfo_t *EGroup;
	EvClassInfo_t *HashBase;
	EvClassInfo_t *ClassBase;
	EvDestBase_t *EventBase;
	unsigned long Flags;

	read_lock_irqsave(&EvGroupLock, Flags);
	if ((EGroup = EvGetGroupBase(groupID)) == NULL) {
		read_unlock_irqrestore(&EvGroupLock, Flags);
		return -EV_ERROR_GROUP_EXIST;
	}

	HashBase = EvGetHashBase(EGroup, classID);

	spin_lock(&HashBase->EciLock);
	read_unlock(&EvGroupLock);

	if ((EventBase = EvFindEventBase(classID,HashBase,&ClassBase))==NULL) {
		spin_unlock_irqrestore(&HashBase->EciLock, Flags);
		return -EV_ERROR_CLASS_EXISTS;
	}

	if (EvCheckAccessCode(ClassBase->EciAccessCode, oldCode)) {
		spin_unlock_irqrestore(&HashBase->EciLock, Flags);
		return -EV_ERROR_CLASS_ACCESS;
	}

	ClassBase->EciAccessCode = newCode;
	spin_unlock_irqrestore(&HashBase->EciLock, Flags);
	return EV_NOERR;
}
Пример #2
0
/*
 * 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;
}
Пример #3
0
int
EvSubscribeGroupEvents(EvUserID_t userID,
                       EvGroupID_t groupID, EvAccess_t accessCode,
                       int (*kernelCB)(EvUserID_t, int, EvGroupID_t,
                                       EvGroupID_t, EvClassID_t, EvEventID_t,
                                       int, int, int, int, int, void *))
{
    EvKernelInfo_t *EventUser;
    EvGroupInfo_t *EGroup;
    unsigned long Flags;

    read_lock_irqsave(&EvUsersLock, Flags);
    if ((EventUser = EvCheckUser(userID)) == NULL) {
        read_unlock_irqrestore(&EvUsersLock, Flags);
        return -EV_ERROR_USER_EXISTS;
    }

    write_lock(&EvGroupLock);
    read_unlock(&EvUsersLock);

    if ((EGroup = EvGetGroupBase(groupID)) == NULL) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_EXIST;
    }

    /* Check the access code for the group. */
    if (EvCheckAccessCode(EGroup->EgiAccessCode, accessCode)) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_ACCESS;
    }

    /* Check that there are no current control processes. */
    if (EGroup->EgiGroupDest.EdID != 0) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_BUSY;
    }

    EGroup->EgiGroupDest.EdPri = 0;		/* Not used. */
    EGroup->EgiGroupDest.EdID = userID;
    EGroup->EgiGroupDest.EdUinfo = NULL;
    EGroup->EgiGroupDest.EdCB = kernelCB;
    EGroup->EgiGroupDest.EdKinfo = EventUser;

    EGroup->EgiUseCount++;

    write_unlock_irqrestore(&EvGroupLock, Flags);
    return EV_NOERR;
}
Пример #4
0
/* This function is as yet incomplete and is here for a particular use.  More
 * to follow.  DO NOT USE.
 */
int
EvTakeOverMaster(EvGroupID_t groupID, EvGroupID_t memberID,
                 EvAccess_t accessCode)
{
    EvGroupInfo_t *EGroup = EvGroupHead;
    unsigned long Flags;

    write_lock_irqsave(&EvGroupLock, Flags);

    /* Has the event group already been created or not? */
    while (EGroup && (EGroup->EgiID != groupID)) {
        EGroup = EGroup->EgiNext;
    }

    if (EGroup == NULL) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_EXIST;
    }

    /* If this is not a master group control the error */
    if (EGroup->EgiType != EG_MEMBER) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_TYPE;
    }

    /* Permissions? */
    if (EvCheckAccessCode(EGroup->EgiAccessCode, accessCode)) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_ACCESS;
    }

    if (memberID == EGroup->EgiMemberID) {
        /* This instance is taking over as master. */
        EGroup->EgiType = EG_MASTER;
        EGroup->EgiMasterID = EGroup->EgiMemberID;
        EGroup->EgiNextMemberID = memberID + 1;
    } else {
        /* Set the new master instance. */
    }

    write_unlock_irqrestore(&EvGroupLock, Flags);
    return EV_NOERR;
}
Пример #5
0
int
EvSetGroupAccessCode(EvGroupID_t groupID,
		     EvAccess_t oldCode, EvAccess_t newCode)
{
	EvGroupInfo_t *EGroup;
	unsigned long Flags;

	read_lock_irqsave(&EvGroupLock, Flags);
	if ((EGroup = EvGetGroupBase(groupID)) == NULL) {
		read_unlock_irqrestore(&EvGroupLock, Flags);
		return -EV_ERROR_GROUP_EXIST;
	}

	if (EvCheckAccessCode(EGroup->EgiAccessCode, oldCode)) {
		read_unlock_irqrestore(&EvGroupLock, Flags);
		return -EV_ERROR_GROUP_ACCESS;
	}

	EGroup->EgiAccessCode = newCode;
	write_unlock_irqrestore(&EvGroupLock, Flags);
	return EV_NOERR;
}
Пример #6
0
/*
 * EvSubscribeEvent() subscribes a kernel component to recieve
 * an event.  If the event call back function kernelCB is specified
 * events will be delivered by calling this function.  Otherwise 
 * events will be placed on an internal event queue and the queue must
 * be polled using the EvGetEvent function.
 *
 * This function subscribes to an event localy.  It does not attempt to
 * inform a remote master that a subscriber has been attached.  This
 * should be added in a later version of the function.
 */
int
EvSubscribeEvent(EvUserID_t userID, EvPri_t pri,
		 EvGroupID_t groupID, EvClassID_t classID,
		 EvEventID_t eventID, EvAccess_t accessCode,
		 int (*kernelCB)(EvUserID_t, EvPri_t, EvGroupID_t,
				 EvGroupID_t, EvClassID_t, EvEventID_t,
				 int, int, int, int, int, void *))
{
	EvDest_t *EventDestP = NULL;
	EvDest_t *TmpDestP = NULL;
	EvDest_t *LastEventDestP = NULL;
	EvDestBase_t *EventBase;
	EvKernelInfo_t *EventUser;
	EvGroupInfo_t *EGroup;
	EvClassInfo_t *HashBase;
	EvClassInfo_t *ClassBase;
	unsigned long Flags;

	/* Check the user ID for validity. */
	read_lock_irqsave(&EvUsersLock, Flags);
	if ((EventUser = EvCheckUser(userID)) == NULL) {
		read_unlock_irqrestore(&EvUsersLock, Flags);
		return -EV_ERROR_USER_EXISTS;
	}

	/* Assume the Event user returned status will no change during
	 * the life of this request.
	 */
	read_lock(&EvGroupLock);
	read_unlock(&EvUsersLock);

	/* Get the event group pointer. */
	if ((EGroup = EvGetGroupBase(groupID)) == NULL) {
		read_unlock_irqrestore(&EvGroupLock, Flags);
		return -EV_ERROR_GROUP_EXIST;
	}

	HashBase = EvGetHashBase(EGroup, classID);

	/* Find the top level entry for this class of events. */
	if ((EventBase = EvFindEventBase(classID,HashBase,&ClassBase)) == NULL){
		read_unlock_irqrestore(&EvGroupLock, Flags);
		return -EV_ERROR_CLASS_EXISTS;
	}

	spin_lock(&ClassBase->EciLock);
	read_unlock(&EvGroupLock);

	/* Check permissions. */
	if (EvCheckAccessCode(ClassBase->EciAccessCode, accessCode)) {
		spin_unlock_irqrestore(&ClassBase->EciLock, Flags);
		return -EV_ERROR_CLASS_ACCESS;
	}

	/* search until the event is found in this catagory or until the
	 * last blank element on the list if found.
	 */
	while (EventBase->EdbNext != NULL) {
		if (EventBase->EdbEvent == eventID) {
			EventDestP = &EventBase->EdbDestQ;
			break;
		}
		EventBase = EventBase->EdbNext;
	}

	/* If no destination pointer has been identified for a chain
	 * search then this event type has not yet been registered by anybody
	 * so fill in the last empty list element and create a new empty one
	 * to inidcate end of list.
	 */
	if (EventDestP == NULL) {
		EventBase->EdbEvent = eventID;
		EventBase->EdbUseCount = 0;

		/* Create the next empty element to indicate end of list. */
		if ((EventBase->EdbNext = kmalloc(sizeof(EvDestBase_t),
							GFP_ATOMIC)) == NULL) {
			spin_unlock_irqrestore(&ClassBase->EciLock, Flags);
			return -EV_ERROR_MEM_ALLOC;
		}

		EventBase->EdbNext->EdbNext = NULL;

		EventDestP = &EventBase->EdbDestQ;
		EventDestP->EdNext = kmalloc(sizeof(EvDest_t), GFP_ATOMIC);
		EventDestP->EdNext->EdNext = NULL;

		 goto EvFillInKernelRequestPacket;
	}

	/* Now search to see if this file descriptor already has registered
	 * for this event type.
	 */
	while (EventDestP->EdNext != NULL) {
		if (EventDestP->EdID == userID) {
			spin_unlock_irqrestore(&ClassBase->EciLock, Flags);
			return -EV_ERROR_CLASS_BUSY;
				
		}

		LastEventDestP = EventDestP;
		EventDestP = EventDestP->EdNext;
	}

	/* Now record the destination and create a new empty element to 
	 * indicate end of list.
	 */

	/* Most registrations go at the end of the list. */
	if ((LastEventDestP != NULL) && (LastEventDestP->EdPri >= pri)) {
		if ((EventDestP->EdNext = kmalloc(sizeof(EvDest_t),
							GFP_ATOMIC)) == NULL) {
			spin_unlock_irqrestore(&ClassBase->EciLock, Flags);
			return -EV_ERROR_MEM_ALLOC;
		}

		EventDestP->EdNext->EdNext = NULL;
		goto EvFillInKernelRequestPacket;
	}

	EventDestP = &EventBase->EdbDestQ;

	/* Check the priority against the top element */
	if (EventDestP->EdPri >= pri) {
		/* Priority of event places it somewhere in the middle */
		while (EventDestP->EdNext->EdPri >= pri) {
			EventDestP = EventDestP->EdNext;
		}
	}

	if ((TmpDestP = kmalloc(sizeof(EvDest_t), GFP_ATOMIC)) == NULL) {
		spin_unlock_irqrestore(&ClassBase->EciLock, Flags);
		return -EV_ERROR_MEM_ALLOC;
	}

	TmpDestP->EdPri = EventDestP->EdPri;
	TmpDestP->EdUinfo = EventDestP->EdUinfo;
	TmpDestP->EdCB = EventDestP->EdCB;
	TmpDestP->EdID = EventDestP->EdID;
	TmpDestP->EdKinfo = EventDestP->EdKinfo;
	TmpDestP->EdNext = EventDestP->EdNext;
	EventDestP->EdNext = TmpDestP;

EvFillInKernelRequestPacket:
	EventBase->EdbUseCount++;
	EventDestP->EdPri = pri;
	EventDestP->EdUinfo = NULL;
	EventDestP->EdID = userID;
	EventDestP->EdCB = kernelCB;

	EventDestP->EdKinfo = EventUser;

	ClassBase->EciUseCount++;

	spin_unlock_irqrestore(&ClassBase->EciLock, Flags);
	return EV_NOERR;
}
Пример #7
0
int
EvInternalUnRegisterEventClass(EvGroupInfo_t *eGroup, EvClassID_t classID,
			    EvAccess_t accessCode)
{
	EvClassInfo_t *HashBase;
	EvClassInfo_t* HashDel;

	HashBase = EvGetHashBase(eGroup, classID);

	/* Does this hash have any classes assigned? */
	if (HashBase->EciNext == NULL) {
		return -EV_ERROR_CLASS_EXISTS;
	}

	/* Is the top element his class? */
	if (HashBase->EciClass == classID) {
		/* If subscribers use count is not zero then return error. */
		if (HashBase->EciUseCount != 0) {
			return -EV_ERROR_CLASS_BUSY;
		}

		if (EvCheckAccessCode(HashBase->EciAccessCode, accessCode)) {
			return -EV_ERROR_CLASS_ACCESS;
		}

		HashDel = HashBase->EciNext;

		HashBase->EciClass = HashDel->EciClass;
		strncpy(HashBase->EciName, HashDel->EciName, 16);
		HashBase->EciEventQ = HashDel->EciEventQ;
		HashBase->EciNext = HashDel->EciNext;

		goto EvDelHashInfo;
	}

	HashDel = HashBase->EciNext;

	while(HashDel->EciNext != NULL) {
		if (HashDel->EciClass == classID) {
			break;
		}
		HashBase = HashDel;
		HashDel = HashDel->EciNext;
	}

	if (HashDel->EciNext == NULL) {
		return -EV_ERROR_CLASS_EXISTS;
	}

	if (HashDel->EciUseCount != 0) {
		return -EV_ERROR_CLASS_BUSY;
	}

	if (EvCheckAccessCode(HashDel->EciAccessCode, accessCode)) {
		return -EV_ERROR_CLASS_ACCESS;
	}

	HashBase->EciNext = HashDel->EciNext;
	
EvDelHashInfo:
	/* Now reaquire the Group lock decrement the use count and send 
	 * remote packets.
	 */
	eGroup->EgiUseCount--;

	/* If this is a master send remove packets to all members. */
	if (eGroup->EgiType == EG_MASTER) {
		EvSendUnRegClassToMembers(eGroup, classID, accessCode);
	}

	if (HashDel->EciEventQ) {
		kfree(HashDel->EciEventQ);
	}

	kfree(HashDel);

	return EV_NOERR;
}
Пример #8
0
int
EvDetachGroup(EvGroupID_t groupID, EvGroupID_t memberID, EvAccess_t accessCode)
{
    EvGroupInfo_t *EGroup = EvGroupHead;
    unsigned long Flags;
    EvMemberList_t *Member;
    EvMemberList_t *FreeMember;

    write_lock_irqsave(&EvGroupLock, Flags);

    /* Has the event group already been created or not? */
    while (EGroup && (EGroup->EgiID != groupID)) {
        EGroup = EGroup->EgiNext;
    }

    if (EGroup == NULL) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_EXIST;
    }

    /* If this is not a master group control the error */
    if (EGroup->EgiType != EG_MASTER) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_TYPE;
    }

    /* Are there any members registered? */
    if (EGroup->EgiMembers == NULL) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_MEMBER_EXIST;
    }

    /* Permissions? */
    if (EvCheckAccessCode(EGroup->EgiAccessCode, accessCode)) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_ACCESS;
    }

    /* Find the member pointer */
    if (EGroup->EgiMembers->EslID == memberID) {
        FreeMember = EGroup->EgiMembers;
        EGroup->EgiMembers = EGroup->EgiMembers->EslNext;

        /* Do not forget to indicate the member is gone. */
        EGroup->EgiUseCount--;
        write_unlock_irqrestore(&EvGroupLock, Flags);
        kfree(FreeMember);
        return EV_NOERR;
    }

    Member = EGroup->EgiMembers;
    while (Member->EslNext) {
        if (Member->EslNext->EslID == memberID) {
            FreeMember = Member->EslNext;
            Member->EslNext = FreeMember->EslNext;

            /* Do not forget to indicate the member is gone. */
            EGroup->EgiUseCount--;
            write_unlock_irqrestore(&EvGroupLock, Flags);
            kfree(FreeMember);
            return EV_NOERR;
        }
        Member = Member->EslNext;
    }

    write_unlock_irqrestore(&EvGroupLock, Flags);
    return -EV_ERROR_MEMBER_EXIST;
}
Пример #9
0
int
EvAttachGroup(EvGroupID_t groupID, char *memberName,
              EvAccess_t accessCode, EvGroupID_t *memberID)
{
    EvGroupInfo_t *EGroup = EvGroupHead;
    unsigned long Flags;
    EvMemberList_t *Member;

    write_lock_irqsave(&EvGroupLock, Flags);

    /* Has the event group already been created or not? */
    while (EGroup && (EGroup->EgiID != groupID)) {
        EGroup = EGroup->EgiNext;
    }

    if (EGroup == NULL) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_EXIST;
    }

    /* If this is not a master group control the error */
    if (EGroup->EgiType != EG_MASTER) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_TYPE;
    }

    /* Permissions? */
    if (EvCheckAccessCode(EGroup->EgiAccessCode, accessCode)) {
        write_unlock_irqrestore(&EvGroupLock, Flags);
        return -EV_ERROR_GROUP_ACCESS;
    }

    /* Has this member already been registered? */
    Member = EGroup->EgiMembers;
    while (Member) {
        if (!strncmp(Member->EslName, memberName, 16)) {
            return -EV_ERROR_MEMBER_EXIST;
        }
        Member = Member->EslNext;
    }

    /* Now allocate an element to store the member info into. */
    if (EGroup->EgiMembers == NULL) {
        if ((EGroup->EgiMembers = kmalloc(sizeof(EvMemberList_t),
                                          GFP_ATOMIC)) == NULL) {
            write_unlock_irqrestore(&EvGroupLock, Flags);
            return -EV_ERROR_MEM_ALLOC;
        }
        Member = EGroup->EgiMembers;
    } else {
        Member = EGroup->EgiMembers;
        while (Member->EslNext != NULL) {
            Member = Member->EslNext;
        }

        if ((Member->EslNext = kmalloc(sizeof(EvMemberList_t),
                                       GFP_ATOMIC)) == NULL) {
            write_unlock_irqrestore(&EvGroupLock, Flags);
            return -EV_ERROR_MEM_ALLOC;
        }
        Member = Member->EslNext;
    }

    /* Fill in the member information. */
    strncpy(Member->EslName, memberName, 16);
    Member->EslID = EGroup->EgiNextMemberID++;
    Member->EslNext = NULL;

    /* Incrementing use count prevents the master from deleting
     * the event group control structures while remotes are trying
     * to use it;
     */
    EGroup->EgiUseCount++;
    /* Fill in returned member ID value */
    *memberID = Member->EslID;

    write_unlock_irqrestore(&EvGroupLock, Flags);
    return EV_NOERR;;
}