Blame IbAccess/Common/Public/iproc_fs.c

Packit Service 3470d1
/* BEGIN_ICS_COPYRIGHT4 ****************************************
Packit Service 3470d1
Packit Service 3470d1
Copyright (c) 2015, Intel Corporation
Packit Service 3470d1
Packit Service 3470d1
Redistribution and use in source and binary forms, with or without
Packit Service 3470d1
modification, are permitted provided that the following conditions are met:
Packit Service 3470d1
Packit Service 3470d1
    * Redistributions of source code must retain the above copyright notice,
Packit Service 3470d1
      this list of conditions and the following disclaimer.
Packit Service 3470d1
    * Redistributions in binary form must reproduce the above copyright
Packit Service 3470d1
      notice, this list of conditions and the following disclaimer in the
Packit Service 3470d1
     documentation and/or other materials provided with the distribution.
Packit Service 3470d1
    * Neither the name of Intel Corporation nor the names of its contributors
Packit Service 3470d1
      may be used to endorse or promote products derived from this software
Packit Service 3470d1
      without specific prior written permission.
Packit Service 3470d1
Packit Service 3470d1
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit Service 3470d1
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit Service 3470d1
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit Service 3470d1
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit Service 3470d1
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 3470d1
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit Service 3470d1
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit Service 3470d1
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit Service 3470d1
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit Service 3470d1
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 3470d1
Packit Service 3470d1
** END_ICS_COPYRIGHT4   ****************************************/
Packit Service 3470d1
Packit Service 3470d1
#include "imemory.h"
Packit Service 3470d1
#include "idebug.h"
Packit Service 3470d1
#include "iproc_fs.h"
Packit Service 3470d1
Packit Service 3470d1
// General purpose function to support proc file reads
Packit Service 3470d1
//
Packit Service 3470d1
// config_data, config_alloc, total_size - static variables in proc function
Packit Service 3470d1
//		will be managed here to maintain context across multiple read calls to
Packit Service 3470d1
//		this file.
Packit Service 3470d1
// func - function to allocate space to text contents and format it
Packit Service 3470d1
// func_data - will be passed as argument to provide context of what to format
Packit Service 3470d1
// buf, start, offset, maxlen, eof - standard proc read arguments
Packit Service 3470d1
Packit Service 3470d1
IBA_PROC_RET
Packit Service 3470d1
iba_proc_read_wrapper(char **config_data, char **config_alloc, int *total_size,
Packit Service 3470d1
		IBA_PROC_FORMAT_FUNC func, void* func_data,
Packit Service 3470d1
 		char *buf, char **start, IBA_PROC_OFFSET offset, int maxlen,
Packit Service 3470d1
		int *eof)
Packit Service 3470d1
{
Packit Service 3470d1
	int cur_size;
Packit Service 3470d1
Packit Service 3470d1
	if (! *config_data) {
Packit Service 3470d1
		*total_size = 0;	// in case format fails to allocate space
Packit Service 3470d1
		*config_data = *config_alloc = (*func)(func_data, total_size);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	/*
Packit Service 3470d1
	 * How much data is available for read: OS spits reads into 512b blocks
Packit Service 3470d1
	 * and asks each individualy via a separate call to you each time.
Packit Service 3470d1
	 */
Packit Service 3470d1
	cur_size = (*total_size <= maxlen ? *total_size : maxlen);
Packit Service 3470d1
Packit Service 3470d1
	/*
Packit Service 3470d1
	 * Is this the last read.. do something to generate
Packit Service 3470d1
	 * an EOF
Packit Service 3470d1
	 */
Packit Service 3470d1
	if (cur_size <= 0) {
Packit Service 3470d1
		*config_data = NULL;
Packit Service 3470d1
		if (*config_alloc != NULL)
Packit Service 3470d1
			MemoryDeallocate(*config_alloc);
Packit Service 3470d1
		*config_alloc = NULL;
Packit Service 3470d1
		*eof = 1;
Packit Service 3470d1
		return 0;
Packit Service 3470d1
	}
Packit Service 3470d1
	MemoryCopy((void *)buf, (void *)*config_data, cur_size);
Packit Service 3470d1
Packit Service 3470d1
	/*
Packit Service 3470d1
	 * setup for next call
Packit Service 3470d1
	 */
Packit Service 3470d1
	*total_size -= cur_size; // Compute #bytes left to deliver.
Packit Service 3470d1
	*config_data += cur_size;
Packit Service 3470d1
Packit Service 3470d1
	if (*total_size <= 0)
Packit Service 3470d1
		*eof = 1;
Packit Service 3470d1
	else
Packit Service 3470d1
		*eof = 0;
Packit Service 3470d1
Packit Service 3470d1
	*start = (char *)(uintn)cur_size;
Packit Service 3470d1
	return cur_size;
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
void
Packit Service 3470d1
SimpleProcInitState(SIMPLE_PROC *pProc)
Packit Service 3470d1
{
Packit Service 3470d1
	MemoryClear(pProc, sizeof(*pProc));
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
// internal format function if callback occurs for
Packit Service 3470d1
// /proc object which is uninitialize (eg. being destroyed)
Packit Service 3470d1
static
Packit Service 3470d1
char * SimpleProcFormatUninit(void *data, int* total_size)
Packit Service 3470d1
{
Packit Service 3470d1
	return NULL;
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
static
Packit Service 3470d1
IBA_PROC_RET SimpleProcRead(char *buf, char **start, IBA_PROC_OFFSET offset, int maxlen, int *eof, void *data)
Packit Service 3470d1
{
Packit Service 3470d1
	SIMPLE_PROC *pProc = (SIMPLE_PROC*)data;
Packit Service 3470d1
Packit Service 3470d1
	return iba_proc_read_wrapper(&pProc->config_data, &pProc->config_alloc,
Packit Service 3470d1
			&pProc->total_size,
Packit Service 3470d1
			pProc->Initialized ? pProc->FormatFunc
Packit Service 3470d1
					: SimpleProcFormatUninit,
Packit Service 3470d1
			pProc->Context,
Packit Service 3470d1
			buf, start, offset, maxlen, eof);
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
static
Packit Service 3470d1
IBA_PROC_RET SimpleProcWrite(IBA_PROC_FILE *file, const char *buffer, unsigned long length, void *data)
Packit Service 3470d1
{
Packit Service 3470d1
	SIMPLE_PROC *pProc = (SIMPLE_PROC*)data;
Packit Service 3470d1
Packit Service 3470d1
	if (pProc->Initialized);
Packit Service 3470d1
		(*pProc->ClearFunc)(pProc->Context);
Packit Service 3470d1
	return length;
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
// create and initialize /proc file
Packit Service 3470d1
// Inputs:
Packit Service 3470d1
//	pProc - object to initialize
Packit Service 3470d1
//	Name - relative filename in ProcDir
Packit Service 3470d1
//	ProcDir - parent directory
Packit Service 3470d1
//	Context - context to pass to FormatFunc and ClearFunc
Packit Service 3470d1
//	FormatFunc - function to allocate and format /proc read data
Packit Service 3470d1
//	ClearFunc - function to clear data in response to /proc write
Packit Service 3470d1
// Outputs:
Packit Service 3470d1
//	None
Packit Service 3470d1
// Returns:
Packit Service 3470d1
//	true - initialized and callbacks will begin on user access to /proc
Packit Service 3470d1
//	false - unable to create
Packit Service 3470d1
//
Packit Service 3470d1
// must be called in a preemptable context
Packit Service 3470d1
//
Packit Service 3470d1
boolean
Packit Service 3470d1
SimpleProcInit(SIMPLE_PROC *pProc, const char* Name, IBA_PROC_NODE *ProcDir, 
Packit Service 3470d1
		void *Context, IBA_PROC_FORMAT_FUNC FormatFunc,
Packit Service 3470d1
		OPTIONAL SIMPLE_PROC_CLEAR_FUNC ClearFunc)
Packit Service 3470d1
{
Packit Service 3470d1
	IBA_PROC_NODE 		*entry;
Packit Service 3470d1
Packit Service 3470d1
	ASSERT(! pProc->Initialized);
Packit Service 3470d1
	ASSERT(FormatFunc);
Packit Service 3470d1
	ASSERT(Name);
Packit Service 3470d1
	pProc->Context = Context;
Packit Service 3470d1
	strncpy(pProc->Name, Name, SIMPLE_PROC_NAME_LEN-1);
Packit Service 3470d1
	pProc->Name[SIMPLE_PROC_NAME_LEN-1] = '\0';
Packit Service 3470d1
	pProc->ProcDir = ProcDir;
Packit Service 3470d1
	pProc->FormatFunc = FormatFunc;
Packit Service 3470d1
	pProc->ClearFunc = ClearFunc;
Packit Service 3470d1
	
Packit Service 3470d1
	entry = iba_create_proc_entry(pProc->Name,
Packit Service 3470d1
				IBA_PROC_MODE_IFREG | IBA_PROC_MODE_IRUGOWUG,
Packit Service 3470d1
				pProc->ProcDir);
Packit Service 3470d1
	if (! entry)
Packit Service 3470d1
	{
Packit Service 3470d1
		MsgOut("Cannot create proc entry: %s\n", pProc->Name);
Packit Service 3470d1
		return FALSE;
Packit Service 3470d1
	}
Packit Service 3470d1
	iba_set_proc_data(entry, pProc);
Packit Service 3470d1
	iba_set_proc_read_func(entry, SimpleProcRead);
Packit Service 3470d1
	iba_set_proc_write_func(entry, ClearFunc?SimpleProcWrite:NULL);
Packit Service 3470d1
	pProc->Initialized = TRUE;
Packit Service 3470d1
	return TRUE;
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
void
Packit Service 3470d1
SimpleProcDestroy(SIMPLE_PROC *pProc)
Packit Service 3470d1
{
Packit Service 3470d1
	if (pProc->Initialized)
Packit Service 3470d1
		iba_remove_proc_entry(pProc->Name, pProc->ProcDir);
Packit Service 3470d1
	MemoryClear(pProc, sizeof(*pProc));
Packit Service 3470d1
}