// resouce manager
//---------------------
int io_devctl(resmgr_context_t *ctp, io_devctl_t *msg,
RESMGR_OCB_T *ocb) {
int nbytes, status, previous;
ADMXRC_IOCTLS_GETVERSIONINFO *pver ;
union {
data_t data;
int data32;
// … other devctl types you can receive
} *rx_data;
/*
Let common code handle DCMD ALL * cases.
You can do this before or after you intercept devctl’s depending
on your intentions. Here we aren’t using any pre-defined values
so let the system ones be handled first.
*/
if ((status = iofunc_devctl_default(ctp, msg,
ocb)) != _RESMGR_DEFAULT) {
return(status);
}
status = nbytes = 0;
/*
Note this assumes that you can fit the entire data portion of
the devctl into one message. In reality you should probably
perform a MsgReadv() once you know the type of message you
have received to suck all of the data in rather than assuming
it all fits in the message. We have set in our main routine
that we’ll accept a total message size of up to 2k so we
don’t worry about it in this example where we deal with ints.
*/
rx_data = _DEVCTL_DATA(msg->i);
/*
Three examples of devctl operations.
SET: Setting a value (int) in the server
GET: Getting a value (int) from the server
SETGET: Setting a new value and returning with the previous value
*/
switch (msg->i.dcmd) {
case MY_DEVCTL_SETVAL:
global_integer = rx_data->data32;
nbytes = 0;
break;
case MY_DEVCTL_GETVAL:
rx_data->data32 = global_integer;
nbytes = sizeof(rx_data->data32);
break;
case MY_DEVCTL_SETGET:
previous = global_integer;
global_integer = rx_data->data.tx;
rx_data->data.rx = previous; //Overwrites tx data
nbytes = sizeof(rx_data->data.rx);
pver = (ADMXRC_IOCTLS_GETVERSIONINFO*)
rx_data->data.p ;
printf (“addr %p \n”, pver);
pver->out.major = (unsigned char) 3 ;
pver->out.minor = (unsigned char) 6 ;
break;
default:
return(ENOSYS);
}
/* Clear the return message … note we saved our data after this /
memset(&msg->o, 0, sizeof(msg->o));
/
If you wanted to pass something different to the return
field of the devctl() you could do it through this member.
/
msg->o.ret_val = status;
/ Indicate the number of bytes and return the message */
msg->o.nbytes = nbytes;
return( _RESMGR_PTR(ctp, &msg->o,
sizeof(msg->o) + nbytes));
}
//----------------------
//----------------------------
program client
//---------------------------
typedef union _ADMXRC_IOCTLS_GETVERSIONINFO {
struct {
unsigned char major;
unsigned char minor;
} out;
} ADMXRC_IOCTLS_GETVERSIONINFO;
typedef union my_devctl_msg {
int tx; //Filled by client on send
int rx; //Filled by server on reply
void * p ;
} data_t;
#define MY_CMD_CODE 1
#define MY_DEVCTL_GETVAL __DIOF( _DCMD_MISC, MY_CMD_CODE + 0, int
)
#define MY_DEVCTL_SETVAL __DIOT( _DCMD_MISC, MY_CMD_CODE + 1, int
)
#define MY_DEVCTL_SETGET __DIOTF( _DCMD_MISC, MY_CMD_CODE + 2,
union my_devc
tl_msg )
int main(int argc, char **argv)
{
int fd, ret, val;
ADMXRC_IOCTLS_GETVERSIONINFO info;
data_t data;
if ((fd = open("/dev/sample0",
O_RDONLY)) == -1) {
return(1);
}
//…
memset(&data, 0, sizeof(data));
data.tx = 50;
data.p = &info ;
ret = devctl(fd, MY_DEVCTL_SETGET, &data,
sizeof(data), NULL);
printf (“version %d.%d”,info.out.major,
info.out.minor) ;
return(0);
}
the output of program client is:
vesion 0.0 , when it must be 3.6
the problem is the following:
I think that when calls io_devctl(----)
…
pver = (ADMXRC_IOCTLS_GETVERSIONINFO*)
rx_data->data.p ;
…
[b:aad0ffa63d]pver[/b:aad0ffa63d] aims to address of memory, but in
memory space of driver and not of client.
then I read and I write in memory but of driver, when i would have to
read and write in memory but of the process client.
somebody can say to me, how I do that? read and write in the space of
memory but of the process client
is possible that?
please! help!!!