data disarranged during return from devctl

Hi all,

i have a problem that my data is disarranged during the return of devctl function to my resource manager.

for example, i have a strucure:

typedef struct
{
  uint16_t          data1;
  uint16_t          data2;
  uint32_t          data3;
  uint32_t          data4;
} my_type;

typedef struct
{
  uint16_t        id;  
  union
  {
    struct
    {
      uint16_t    num_1;
      uint16_t    num_2;
      uint16_t    num_3;        
    } req;  /* request message */
    struct
    {
      uint16_t    num_1;
      uint16_t    num_2;
      uint16_t    num_3;     
      uint16_t    num_of_data;
      my_type   data[32];      
    } resp; /* response message */
  }ReqResp;
} My_ReqResp;

i pass the pointer of the structure to the resource manager with id, and req filled with the request value. The resource manager reads the request and add the “num_of_data” and “data” at the end of the structure.

As i debug the program, it works fine until the end of my resource manager, but when it returns to the calling program, the data is disarranged.

for example, i give in the request:

id = 1, num_1=0, num_2=0, num_3=0

this data will be passed using devctl() to my resource manager, the
resource manager reads the request and pad (without changing the request parameter values):

num_of_data = 0x0003
data[1].data1 = 0x0002
data[1].data2 = 0x0000
data[1].data3 = 0x003fa910
data[1].data 4= 0x0000006
.... (and so on)

after returned to the calling function the response will be:

num_of_data = 0x00ff
data[1].data1 = 0x0000
data[1].data2 = 0x0003
data[1].data3 = 0x00020000
data[1].data 4= 0x003fa910
.... (and so on)

it seems clearly that the data is disarranged. i tried to put some dummy bytes inside the structure but it doesnt work.

here is how my devctl handler look likes

int io_devctl( resmgr_context_t *ctp, io_devctl_t *msg, struct ocb *ocb)
{
  int nbytes, ret;
  uint16_t len, resp_len;
  char *pdata;

  /* number of bytes received */
  len = (uint16_t) msg->i.nbytes;

  /* execute devctl handler default function */
  ret = iofunc_devctl_default(ctp, msg, &(ocb->hdr));
  if(ret != _RESMGR_DEFAULT)
  {
    return ret;
  }
  
  ret = nbytes = 0;

  switch(msg->i.dcmd)
  {
    case 0:
    {
      /* pointer to the received data */
      pdata = _DEVCTL_DATA(msg->i);	

      /* process data type 0 */
      ret = Proc0(pdata, &resp_len);

      break;
    }

    case 1:
    {
      /* pointer to the received data */
      pdata = _DEVCTL_DATA(msg->i);	

      /* process data type 0 */
      ret = Proc1(pdata, &resp_len);

      break;
    }

    default:
    {
      return (ENOSYS);
    }
  }
  
  /* clear return message */
  memset(&msg->o, 0, sizeof(msg->o));
  
  msg->o.ret_val = nbytes;
  msg->o.nbytes = nbytes;
  
  ret = (_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + nbytes));
  
  return ret;
}

seems that i am doing just what it is told by the guidelines in “Writing Resource Manager”. but what is actually the problem? i dont really get it by the _RESMGR_PTR() macros also, since i looked into the header files, and found:

#define _RESMGR_NPARTS(_num)	(-(_num))				/* Reply with this many parts from ctp->iov */
#define _RESMGR_PTR(_h,_p,_n)	(SETIOV((_h)->iov+0,(_p),(_n)),_RESMGR_NPARTS(1))

that means it always returns -1. am i right?
getting confused here.

thanks for any hints

Hallo,

i found the solution of this problem myself finally. It seems that i did a mistake using the devctl() function parameter n_bytes.

In the example i gave before, i gave the length of the request in the parameter n_bytes, then the resource manager will pad some data at the end of the buffer.

This padded data will of course not be correctly returned to the client program, since it is written outside the valid area given by the n_bytes parameter.

I think the description of n_bytes parameter of devctl() function should be made clearer due to this problem.