#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <sys/neutrino.h>
#include <sys/resmgr.h>
void options (int argc, char **argv);
int io_close( resmgr_context_t *ctp, void *reserved,RESMGR_OCB_T *ocb);
int io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra);
int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb);
int io_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb);
//int io_lseek ( resmgr_context_t *ctp,io_lseek_t *msg,RESMGR_OCB_T *ocb);
static char* progname="res_mgr_nvram";
resmgr_connect_funcs_t connect_funcs;
resmgr_io_funcs_t io_funcs;
dispatch_t *dpp;
resmgr_attr_t rattr;
dispatch_context_t *ctp;
iofunc_attr_t ioattr;
int optv =0; // -v for verbose operation
#define NVRAM_SIZE_IN_BYTE (1024*1024)
static unsigned char nvramArray[NVRAM_SIZE_IN_BYTE];
static unsigned char rwbuf[NVRAM_SIZE_IN_BYTE]={0x00};
int main (int argc, char **argv)
{
int pathID;
printf ("%s: starting...\n", progname);
memset(nvramArray,0x00,sizeof(nvramArray));
dpp = dispatch_create ();
if (dpp == NULL) {
fprintf (stderr, "%s: couldn't dispatch_create: %s\n",
progname, strerror (errno));
exit (1);
}
memset (&rattr, 0, sizeof (rattr));
iofunc_func_init (_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);
connect_funcs.open = io_open;
io_funcs.read = io_read;
io_funcs.write = io_write;
io_funcs.close_ocb = io_close;
iofunc_attr_init (&ioattr, S_IFCHR | 0666, NULL, NULL);
pathID = resmgr_attach (dpp, &rattr, "/dev/sample_nvram",
_FTYPE_ANY, 0, &connect_funcs, &io_funcs, &ioattr);
if (pathID == -1) {
fprintf (stderr, "%s: couldn't attach pathname: %s\n",
progname, strerror (errno));
exit (1);
}
ctp = dispatch_context_alloc (dpp);
while (1) {
if ((ctp = dispatch_block (ctp)) == NULL) {
fprintf (stderr, "%s: dispatch_block failed: %s\n",
progname, strerror (errno));
exit (1);
}
dispatch_handler (ctp);
}
}
int io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
{
if (optv) {
printf ("%s: in io_open\n", progname);
}
return (iofunc_open_default (ctp, msg, handle, extra));
}
int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb)
{
int status;
char *buf;
uint64_t limit,left;
uint32_t sizeToRead,offset,i;
if (optv) {
printf ("%s: in io_read\n", progname);
}
if ((status = iofunc_read_verify(ctp, msg, ocb, NULL)) != EOK) {
return (status);
}
if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) {
return (ENOSYS);
}
limit=NVRAM_SIZE_IN_BYTE;
if(ocb->offset>limit)
{
printf("#err %s current offset 0x%llx >= nvram size limit 0x%llx\n",__func__, ocb->offset,limit);
return (ENOSYS);
}
left=limit-ocb->offset;
offset=ocb->offset;
if(0==left)
{
sizeToRead=0;
}
else if(msg->i.nbytes>left)
{
sizeToRead=left;
}
else
{
sizeToRead=msg->i.nbytes;
}
if (optv)
{
printf("got read of 0x%x bytes, current offset 0x%x sizeToRead 0x%x\n", msg->i.nbytes,ocb->offset,sizeToRead);
}
_IO_SET_READ_NBYTES(ctp, sizeToRead);
ocb->offset+=(int)sizeToRead;
buf=nvramArray;
if(sizeToRead>0)
{
#if 1
/*only debug*/
for(i=0;i<sizeToRead;i++)
{
//printf("Get nvram offset[0x%08x] value 0x%02x\n",i+offset,nvramArray[i+offset]);
}
#endif
resmgr_msgwrite (ctp, &buf[offset], sizeToRead, 0);
}
if (sizeToRead > 0)
{
ocb->attr->flags |= IOFUNC_ATTR_ATIME;
}
//printf("ocb->offset= 0x%x fornow\n",ocb->offset);
return (_RESMGR_NPARTS (0));
}
int io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb)
{
int status;
char *buf;
uint64_t limit,left;
uint32_t sizeToWrite,offset,i;
if (optv) {
printf ("%s: in io_write\n", progname);
}
if ((status = iofunc_write_verify(ctp, msg, ocb, NULL)) != EOK)
{
printf ("#err iofunc_write_verify ret %d \n", status);
return (status);
}
if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) {
return (ENOSYS);
}
if (optv)
{
printf("got write of 0x%x bytes, current offset 0x%llx\n", msg->i.nbytes,ocb->offset);
}
limit=NVRAM_SIZE_IN_BYTE;
if(ocb->offset>=limit)
{
printf("#err %s current offset 0x%x >= nvram size limit 0x%llx\n",__func__, ocb->offset,limit);
return (ENOSYS);
}
left=limit-ocb->offset;
offset=ocb->offset;
if(msg->i.nbytes > left)
{
sizeToWrite=left;
}
else
{
sizeToWrite=msg->i.nbytes;
}
_IO_SET_WRITE_NBYTES (ctp, sizeToWrite);
ocb->offset+=(int)sizeToWrite;
buf=rwbuf;
resmgr_msgread( ctp, buf, sizeToWrite, sizeof(msg->i));
for(i=0;i<sizeToWrite;i++)
{
if (optv)
{
printf("Set nvram offset[0x%08x] from 0x%02x to 0x%02x\n",i+offset,nvramArray[i+offset],(unsigned char)buf[i]);
}
nvramArray[i+offset]=buf[i];
}
if (sizeToWrite > 0)
{
ocb->attr->flags |= IOFUNC_ATTR_MTIME | IOFUNC_ATTR_CTIME;
}
//printf("ocb->offset= 0x%x fornow\n",ocb->offset);
return (_RESMGR_NPARTS (0));
}
int io_close( resmgr_context_t *ctp, void *reserved,RESMGR_OCB_T *ocb)
{
if (optv) {
printf ("%s: in io_close\n", progname);
}
return (iofunc_close_ocb_default(ctp, reserved, ocb));
}
评论0