Beispiel #1
0
/*
 *  ======== NTFY_Notify ========
 *  Purpose:
 *      Execute notify function (signal event) for every
 *      element in the notification list that is to be notified about the
 *      event specified in uEventMask.
 */
void NTFY_Notify(struct NTFY_OBJECT *hNtfy, u32 uEventMask)
{
	struct NOTIFICATION *pNotify;

	DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE));

	/*
	 *  Go through notifyList and notify all clients registered for
	 *  uEventMask events.
	 */

	(void) SYNC_EnterCS(hNtfy->hSync);

	pNotify = (struct NOTIFICATION *)LST_First(hNtfy->notifyList);
	while (pNotify != NULL) {
		if (pNotify->uEventMask & uEventMask) {
			/* Notify */
			if (pNotify->uNotifyType == DSP_SIGNALEVENT)
				(void)SYNC_SetEvent(pNotify->hSync);

		}
		pNotify = (struct NOTIFICATION *)LST_Next(hNtfy->notifyList,
			  (struct list_head *)pNotify);
	}

	(void) SYNC_LeaveCS(hNtfy->hSync);
}
Beispiel #2
0
/*
 *  ======== RMM_free ========
 */
bool RMM_free(struct RMM_TargetObj *target, u32 segid, u32 addr, u32 size,
	bool reserved)

{
	struct RMM_OvlySect *sect;
	bool retVal = true;

	DBC_Require(MEM_IsValidHandle(target, RMM_TARGSIGNATURE));

	DBC_Require(reserved || segid < target->numSegs);
	DBC_Require(reserved || (addr >= target->segTab[segid].base &&
		   (addr + size) <= (target->segTab[segid].base +
		   target->segTab[segid].length)));

	GT_5trace(RMM_debugMask, GT_ENTER,
		 "RMM_free(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
		 "0x%lx)\n", target, segid, addr, size, reserved);
	/*
	 *  Free or unreserve memory.
	 */
	if (!reserved) {
		retVal = freeBlock(target, segid, addr, size);
		if (retVal)
			target->segTab[segid].number--;

	} else {
		/* Unreserve memory */
		sect = (struct RMM_OvlySect *)LST_First(target->ovlyList);
		while (sect != NULL) {
			if (addr == sect->addr) {
				DBC_Assert(size == sect->size);
				/* Remove from list */
				LST_RemoveElem(target->ovlyList,
					      (struct LST_ELEM *)sect);
				MEM_Free(sect);
				break;
			}
			sect = (struct RMM_OvlySect *)LST_Next(target->ovlyList,
			       (struct LST_ELEM *)sect);
		}
		if (sect == NULL)
			retVal = false;

	}
	return retVal;
}
Beispiel #3
0
/*
 *  ======== RMM_alloc ========
 */
DSP_STATUS RMM_alloc(struct RMM_TargetObj *target, u32 segid, u32 size,
		    u32 align, u32 *dspAddr, bool reserve)
{
	struct RMM_OvlySect *sect;
	struct RMM_OvlySect *prevSect = NULL;
	struct RMM_OvlySect *newSect;
	u32 addr;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(MEM_IsValidHandle(target, RMM_TARGSIGNATURE));
	DBC_Require(dspAddr != NULL);
	DBC_Require(size > 0);
	DBC_Require(reserve || (target->numSegs > 0));
	DBC_Require(cRefs > 0);

	GT_6trace(RMM_debugMask, GT_ENTER,
		 "RMM_alloc(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
		 "0x%lx, 0x%lx)\n", target, segid, size, align, dspAddr,
		 reserve);
	if (!reserve) {
		if (!allocBlock(target, segid, size, align, dspAddr)) {
			status = DSP_EMEMORY;
		} else {
			/* Increment the number of allocated blocks in this
			 * segment */
			target->segTab[segid].number++;
		}
		goto func_end;
	}
	/* An overlay section - See if block is already in use. If not,
	 * insert into the list in ascending address size.  */
	addr = *dspAddr;
	sect = (struct RMM_OvlySect *)LST_First(target->ovlyList);
	/*  Find place to insert new list element. List is sorted from
	 *  smallest to largest address. */
	while (sect != NULL) {
		if (addr <= sect->addr) {
			/* Check for overlap with sect */
			if ((addr + size > sect->addr) || (prevSect &&
			   (prevSect->addr + prevSect->size > addr))) {
				status = DSP_EOVERLAYMEMORY;
			}
			break;
		}
		prevSect = sect;
		sect = (struct RMM_OvlySect *)LST_Next(target->ovlyList,
			(struct LST_ELEM *)sect);
	}
	if (DSP_SUCCEEDED(status)) {
		/* No overlap - allocate list element for new section. */
		newSect = MEM_Calloc(sizeof(struct RMM_OvlySect), MEM_PAGED);
		if (newSect == NULL) {
			status = DSP_EMEMORY;
		} else {
			LST_InitElem((struct LST_ELEM *)newSect);
			newSect->addr = addr;
			newSect->size = size;
			newSect->page = segid;
			if (sect == NULL) {
				/* Put new section at the end of the list */
				LST_PutTail(target->ovlyList,
					   (struct LST_ELEM *)newSect);
			} else {
				/* Put new section just before sect */
				LST_InsertBefore(target->ovlyList,
						(struct LST_ELEM *)newSect,
						(struct LST_ELEM *)sect);
			}
		}
	}
func_end:
	return status;
}
Beispiel #4
0
/*
 *  ======== NTFY_Register ========
 *  Purpose:
 *      Add a notification element to the list. If the notification is already
 *      registered, and uEventMask != 0, the notification will get posted for
 *      events specified in the new event mask. If the notification is already
 *      registered and uEventMask == 0, the notification will be unregistered.
 */
DSP_STATUS NTFY_Register(struct NTFY_OBJECT *hNtfy,
			 struct DSP_NOTIFICATION *hNotification,
			 u32 uEventMask, u32 uNotifyType)
{
	struct NOTIFICATION *pNotify;
	struct SYNC_ATTRS syncAttrs;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE));

	if (hNotification == NULL)
		status = DSP_EHANDLE;

	/* Return DSP_ENOTIMPL if uNotifyType is not supported */
	if (DSP_SUCCEEDED(status)) {
		if (!IsValidNotifyMask(uNotifyType))
			status = DSP_ENOTIMPL;

	}

	if (DSP_FAILED(status))
		return status;

	(void)SYNC_EnterCS(hNtfy->hSync);

	pNotify = (struct NOTIFICATION *)LST_First(hNtfy->notifyList);
	while (pNotify != NULL) {
		/* If there is more than one notification type, each
		 * type may require its own handler code.  */

		if (hNotification->handle == pNotify->hSync) {
			/* found */
			break;
		}
		pNotify = (struct NOTIFICATION *)LST_Next(hNtfy->notifyList,
			  (struct list_head *)pNotify);
	}
	if (pNotify == NULL) {
		/* Not registered */
		if (uEventMask == 0) {
			status = DSP_EVALUE;
		} else {
			/* Allocate NOTIFICATION object, add to list */
			pNotify = MEM_Calloc(sizeof(struct NOTIFICATION),
					     MEM_PAGED);
			if (pNotify == NULL)
				status = DSP_EMEMORY;

		}
		if (DSP_SUCCEEDED(status)) {
			LST_InitElem((struct list_head *)pNotify);
			 /* If there is more than one notification type, each
			 * type may require its own handler code. */
			status = SYNC_OpenEvent(&pNotify->hSync, &syncAttrs);
			hNotification->handle = pNotify->hSync;

			if (DSP_SUCCEEDED(status)) {
				pNotify->uEventMask = uEventMask;
				pNotify->uNotifyType = uNotifyType;
				LST_PutTail(hNtfy->notifyList,
					   (struct list_head *)pNotify);
			} else {
				DeleteNotify(pNotify);
			}
		}
	} else {
		/* Found in list */
		if (uEventMask == 0) {
			/* Remove from list and free */
			LST_RemoveElem(hNtfy->notifyList,
				      (struct list_head *)pNotify);
			DeleteNotify(pNotify);
		} else {
			/* Update notification mask (type shouldn't change) */
			pNotify->uEventMask = uEventMask;
		}
	}
	(void)SYNC_LeaveCS(hNtfy->hSync);
	return status;
}