Blame IbAccess/Common/Public/iproc_fs.c

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