dataspace.c

Go to the documentation of this file.
00001 /* $Id: dataspace.c 23143 2005-11-16 21:29:08Z adam $ */
00002 /*****************************************************************************/
00003 /**
00004  * \file   dsi/lib/src/dataspace.c
00005  * \brief  Control / Data dataspace handling.
00006  *
00007  * \date   07/01/2000
00008  * \author Lars Reuther <reuther@os.inf.tu-dresden.de>
00009  *
00010  * \todo Do not manage attach area for control / data datspaces 
00011  *       (next_map_cds, next_map_dds), use l4rm instead (requires that l4rm
00012  *       provides alligned attachs to be able to map larger areas by just 
00013  *       one flexpage).
00014  * 
00015  * \todo Rethink whole dataspace handling. Who creates/attaches/frees/detaches
00016  *       dataspaces.
00017  */
00018 /*****************************************************************************/
00019 
00020 /* standard/OSKit includes */
00021 #include <stdlib.h>
00022 #include <string.h>
00023 
00024 /* L4/L4Env includes */
00025 #include <l4/sys/types.h>
00026 #include <l4/sys/consts.h>
00027 #include <l4/env/errno.h>
00028 #include <l4/env/env.h>
00029 #include <l4/util/util.h>
00030 #include <l4/util/macros.h>
00031 #include <l4/l4rm/l4rm.h>
00032 #include <l4/dm_mem/dm_mem.h>
00033 
00034 /* private includes */
00035 #include <l4/dsi/dsi.h>
00036 #include "__sync.h"
00037 #include "__socket.h"
00038 #include "__config.h"
00039 #include "__debug.h"
00040 #include "__dataspace.h"
00041 
00042 /*****************************************************************************
00043  * global structures
00044  *****************************************************************************/
00045 
00046 //! dataspace manager id
00047 static l4_threadid_t dsi_dm_id = L4_INVALID_ID;
00048 
00049 /**
00050  * map area control dataspaces
00051  */
00052 static l4_uint32_t cds_map_area = -1;
00053 
00054 /**
00055  * map area data dataspaces
00056  */
00057 static l4_uint32_t dds_map_area = -1;
00058 
00059 /*****************************************************************************
00060  * helpers
00061  *****************************************************************************/
00062 
00063 /*****************************************************************************/
00064 /**
00065  * \brief  Request dataspace manager from L4 environment.
00066  * \ingroup internal
00067  * 
00068  * \return 0 on success (\a dsi_dm_id contains ID of dataspace manager), 
00069  *         -1 if querry failed.
00070  */
00071 /*****************************************************************************/ 
00072 static inline int
00073 __get_dm_id(void)
00074 {
00075   dsi_dm_id = l4env_get_default_dsm();
00076   if (l4_is_invalid_id(dsi_dm_id))
00077     {
00078       Panic("DSI: no dataspace manager found");
00079       dsi_dm_id = L4_INVALID_ID;
00080       return -1;
00081     }
00082   return 0;
00083 }
00084 
00085 /*****************************************************************************/
00086 /**
00087  * \brief  Calculate control dataspace size
00088  * 
00089  * \param  cfg           Stream configuration
00090  *      
00091  * \return Control dataspace size
00092  */
00093 /*****************************************************************************/ 
00094 static inline l4_size_t
00095 __get_ctrl_ds_size(dsi_stream_cfg_t cfg)
00096 {
00097   return sizeof(dsi_ctrl_header_t) + 
00098     cfg.num_packets * sizeof(dsi_packet_t) +
00099     cfg.num_packets * cfg.max_sg *  sizeof(dsi_sg_elem_t);
00100 }
00101 
00102 /*****************************************************************************/
00103 /**
00104  * \brief   Initialize control dataspace
00105  * 
00106  * \param   map_addr     Dataspace map address
00107  * \param   size         Dataspace size
00108  * \param   cfg          Stream configuration
00109  *
00110  * Initialize data structures of control dataspace
00111  */
00112 /*****************************************************************************/ 
00113 static void
00114 __init_ctrl_ds(l4_addr_t map_addr, l4_size_t size, dsi_stream_cfg_t cfg)
00115 {
00116   dsi_ctrl_header_t * header;
00117   dsi_packet_t * packets;
00118   dsi_sg_elem_t * sg_elems;
00119   int i;
00120   
00121   LOGdL(DEBUG_CTRL_DS, "total size %u, header size %u\n" \
00122         " %u packets of size %u\n" \
00123         " %u sg elems of size %u",
00124         size, sizeof(dsi_ctrl_header_t), 
00125         cfg.num_packets, sizeof(dsi_packet_t),
00126         cfg.num_packets * cfg.max_sg, sizeof(dsi_sg_elem_t));
00127   
00128   /* setup dataspace */
00129   header = (dsi_ctrl_header_t *)map_addr;
00130   packets = (dsi_packet_t *)(map_addr + sizeof(dsi_ctrl_header_t));
00131   sg_elems = (dsi_sg_elem_t *)(map_addr + sizeof(dsi_ctrl_header_t) +
00132                                cfg.num_packets * sizeof(dsi_packet_t));
00133 
00134   /* clean dataspace */
00135   memset(header, 0, size);
00136 
00137   /* setup header */
00138   header->num_packets = cfg.num_packets;
00139   header->num_sg_elems = cfg.num_packets * cfg.max_sg;
00140   header->max_sg_len = cfg.max_sg;
00141   header->packets_committed = 0;
00142 
00143   /* setup packet descriptors */
00144   for (i = 0; i < cfg.num_packets; i++)
00145     {
00146       packets[i].tx_sem = DSI_SEMAPHORE_UNLOCKED;
00147       packets[i].rx_sem = DSI_SEMAPHORE_LOCKED;
00148     }
00149 
00150   /* setup scatter gather elements */
00151   for (i = 0; i < cfg.num_packets * cfg.max_sg; i++)
00152     sg_elems[i].flags = DSI_SG_ELEM_UNUSED;
00153 }
00154 
00155 /*****************************************************************************/
00156 /**
00157  * \brief   Map control dataspace, setup pointers in socket structure
00158  * \ingroup internal
00159  * 
00160  * \param   socket       Socket descriptor   
00161  * \param   cfg          Low level stream configuration
00162  * 
00163  * \return 0 on success, error code otherwise:
00164  *         - -#L4_ENOMEM  out of memory attaching dataspace
00165  *         - -#L4_ENOMAP  no map area available
00166  *         - -#L4_EINVAL  invalid argument attaching dataspace
00167  */
00168 /*****************************************************************************/ 
00169 static int
00170 __map_ctrl_ds(dsi_socket_t * socket, dsi_stream_cfg_t cfg)
00171 {
00172   int ret;
00173   l4_size_t size;
00174   void *map_addr;
00175 
00176   /* check map area */
00177   ret = l4dm_mem_size(&socket->ctrl_ds, &size);
00178   if (ret < 0)
00179     {
00180       LOG_Error("DSI: get dataspace size failed: %s (%d)", 
00181                 l4env_errstr(ret), ret);
00182       return -L4_EINVAL;
00183     }
00184   
00185   LOGdL(DEBUG_CTRL_DS,"attaching ctrl dataspace, ds %d at "l4util_idfmt", size %d", 
00186         socket->ctrl_ds.id, l4util_idstr(socket->ctrl_ds.manager), size);
00187   
00188   /* attach dataspace */
00189   if (cds_map_area != -1)
00190     ret = l4rm_area_attach(&socket->ctrl_ds, cds_map_area, size, 0,
00191                            L4DM_RW | L4RM_MAP, &map_addr);
00192   else
00193     ret = l4rm_attach(&socket->ctrl_ds,size, 0, L4DM_RW | L4RM_MAP,
00194                       &map_addr);
00195   if (ret < 0)
00196     {
00197       LOG_Error("DSI: attach dataspace failed: %s (%d)",
00198                 l4env_errstr(ret), ret);
00199       return ret;
00200     }
00201 
00202   /* setup socket pointers */
00203   socket->header = (dsi_ctrl_header_t *)map_addr;
00204   socket->packets = (dsi_packet_t *)((unsigned)map_addr + 
00205                                       sizeof(dsi_ctrl_header_t));
00206   socket->sg_lists = (dsi_sg_elem_t *)((unsigned)map_addr + 
00207                                        sizeof(dsi_ctrl_header_t) +
00208                                        cfg.num_packets * sizeof(dsi_packet_t));
00209   
00210   LOGdL(DEBUG_CTRL_DS, "attached crtl ds to 0x%08lx \n" \
00211         " header at   0x%08lx\n" \
00212         " packets at  0x%08lx\n" \
00213         " sg_lists at 0x%08lx",
00214         (l4_addr_t)map_addr,(l4_addr_t)socket->header, 
00215         (l4_addr_t)socket->packets, (l4_addr_t)socket->sg_lists);
00216   
00217   /* done */
00218   return 0;
00219 }
00220 
00221 /*****************************************************************************
00222  * public library stuff
00223  *****************************************************************************/
00224 
00225 /*****************************************************************************/
00226 /**
00227  * \brief   Allocate and setup control area.
00228  * \ingroup internal
00229  * 
00230  * \param   socket       Socket descriptor
00231  * \param   jcp_stream   Stream description
00232  * \param   cfg          Low level stream configuration
00233  *      
00234  * \return  0 on success, error code otherwise:
00235  *          - -#DSI_ENODSM  dataspace manager not found
00236  *          - -#L4_EIPC     IPC error calling dataspace manager
00237  *          - -#L4_ENOMEM   not enough memory available allocating ctrl area
00238  *                          or attaching dataspace
00239  *          - -#L4_ENOMAP   no map area avaliable mapping ctrl area
00240  *          - -#L4_EINVAL   invalid argument (can happen if the map area is
00241  *                          already used by someone else)
00242  */
00243 /*****************************************************************************/ 
00244 int
00245 dsi_create_ctrl_area(dsi_socket_t * socket, dsi_jcp_stream_t jcp_stream, 
00246                      dsi_stream_cfg_t cfg)
00247 {
00248   int ret;
00249   l4_size_t size = __get_ctrl_ds_size(cfg);
00250 
00251   /* sanity checks */
00252   Assert(socket != NULL);
00253 
00254   /* check dataspace manager */
00255   if (l4_thread_equal(dsi_dm_id,L4_INVALID_ID))
00256     {
00257       if (__get_dm_id())
00258         return -DSI_ENODSM;
00259     }
00260   ASSERT(!l4_thread_equal(dsi_dm_id,L4_INVALID_ID));
00261 
00262   /* align size to page size */
00263   size = l4_round_page(size);
00264 
00265   /* allocate dataspace */
00266   ret = l4dm_mem_open(dsi_dm_id, size, 0, 0, "DSI ctrl area", 
00267                       &socket->ctrl_ds);
00268   if (ret < 0)
00269     {
00270       LOG_Error("DSI: dataspace allocation failed: %s (%d)",
00271                 l4env_errstr(ret), ret);
00272       return ret;
00273     }
00274 
00275   LOGdL(DEBUG_CTRL_DS, "ds %d at "l4util_idfmt, 
00276         socket->ctrl_ds.id, l4util_idstr(socket->ctrl_ds.manager));
00277 
00278   /* map control dataspace and setup pointers in socket */
00279   ret = __map_ctrl_ds(socket, cfg);
00280   if (ret)
00281     {
00282       /* failed to setup control area, release dataspace */
00283       l4dm_close(&socket->ctrl_ds);
00284       return ret;
00285     }
00286 
00287   /* initialize control dataspace structures */
00288   __init_ctrl_ds((l4_addr_t)socket->header, size, cfg);
00289 
00290   /* finish setup */ 
00291   socket->num_packets = socket->header->num_packets;
00292   socket->num_sg_elems = socket->header->num_sg_elems;
00293 
00294   /* done */
00295   return 0;
00296 }
00297 
00298 /*****************************************************************************/
00299 /**
00300  * \brief   Attach and setup control area.
00301  * \ingroup internal
00302  * 
00303  * \param   socket       Socket descriptor
00304  * \param   ctrl_ds      Control dataspace
00305  * \param   jcp_stream   Stream description
00306  * \param   cfg          Low level stream configuration
00307  *      
00308  * \return 0 on success, error code otherwise:
00309  *         - -#L4_EINVAL  invalid dataspace or configuration
00310  *         - -#L4_EPERM   no permissions to access dataspace
00311  *         - -#L4_EIPC    IPC error calling dataspace manager
00312  *         - -#L4_ENOMAP  no map area available to attach dataspace
00313  *         - -#L4_ENOMEM  out of memory attaching dataspace
00314  */
00315 /*****************************************************************************/ 
00316 int
00317 dsi_set_ctrl_area(dsi_socket_t * socket, l4dm_dataspace_t ctrl_ds,
00318                   dsi_jcp_stream_t jcp_stream, dsi_stream_cfg_t cfg)
00319 {
00320   int ret;
00321   l4_size_t size,s;
00322   l4_addr_t map;
00323 
00324   /* sanity checks */
00325   Assert(socket != NULL);
00326 
00327   /* check dataspace */
00328   ret = l4dm_check_rights(&ctrl_ds, L4DM_RW);
00329   if (ret < 0)
00330     {
00331       LOG_Error("DSI: invalid dataspace: %s (%d)", l4env_errstr(ret), ret);
00332       return ret;
00333     }
00334 
00335   /* set control dataspace */
00336   socket->ctrl_ds = ctrl_ds;
00337 
00338   /* map control dataspace, setup pointers in socket structure */
00339   ret = __map_ctrl_ds(socket, cfg);
00340   if (ret)
00341     {
00342       /* failed to setup control area */
00343       return ret;
00344     }
00345 
00346   /* The following is a bit confusing: We have the same information twice.
00347      1. We store it in the write-shared header of the control-area to
00348      communicate it to our peer.
00349      2. We store it in the socket-structure to be resistant against a
00350      malicious peer overwriting the control-area with invalid data.
00351   */
00352   /* Obtain the values from the header of the control area. */
00353   socket->num_packets = socket->header->num_packets;
00354   socket->num_sg_elems = socket->header->num_sg_elems;
00355 
00356   /* sanity check, compare configuration in cfg and control area header */
00357   if ((cfg.num_packets != socket->num_packets) ||
00358       (socket->num_sg_elems != cfg.max_sg * socket->num_packets))
00359     {
00360       LOG_Error("DSI: configuration mismatch in control area");
00361       
00362       /* check if attached area is big enough */
00363       size = sizeof(dsi_ctrl_header_t) + 
00364         socket->num_packets * sizeof(dsi_packet_t) +
00365         socket->num_sg_elems *  sizeof(dsi_sg_elem_t);
00366       
00367       l4dm_mem_size(&socket->ctrl_ds, &s);
00368       if (size > s)
00369         {
00370           Panic("DSI: size mismatch");
00371           return -L4_EINVAL;
00372         }
00373       
00374       /* adapt packet / scatter gather list pointer */
00375       LOG_printf("DSI: adjusting packet / scatter gather list pointers\n");
00376       map = (l4_addr_t)socket->header;
00377       socket->packets = (dsi_packet_t *)(map + sizeof(dsi_ctrl_header_t));
00378       socket->sg_lists = (dsi_sg_elem_t *)
00379         (map + sizeof(dsi_ctrl_header_t) + 
00380          socket->num_packets * sizeof(dsi_packet_t));
00381     }
00382 
00383   return 0;
00384 }
00385 
00386 /*****************************************************************************/
00387 /**
00388  * \brief Release control dataspace.
00389  * \ingroup internal
00390  * 
00391  * \param socket         Socket descriptor
00392  *      
00393  * \return 0 on success, error code otherwise.
00394  *
00395  * Detach control dataspace and close dataspace if we created it.
00396  */
00397 /*****************************************************************************/ 
00398 int
00399 dsi_release_ctrl_area(dsi_socket_t * socket)
00400 {
00401   int ret;
00402   int error = 0;
00403   
00404   LOGdL(DEBUG_CTRL_DS,"detaching control area (ds %d at "l4util_idfmt")",
00405         socket->ctrl_ds.id, l4util_idstr(socket->ctrl_ds.manager));
00406 
00407   /* detach control dataspace */
00408   ret = l4rm_detach(socket->header);
00409   if (ret < 0)
00410     {
00411       LOG_Error("DSI: detach control dataspace failed: %s (%d)",
00412                 l4env_errstr(ret), ret);
00413       error = ret;
00414     }
00415 
00416   if (socket->flags & DSI_SOCKET_FREE_CTRL)
00417     {
00418       /* we created the control dataspace, close it */
00419       ret = l4dm_close(&socket->ctrl_ds);
00420       if (ret < 0)
00421         {
00422           LOG_Error("DSI: close control dataspace failed: %s (%d)",
00423                     l4env_errstr(ret), ret);
00424           error = ret;
00425         }
00426     }
00427 
00428   /* done */
00429   return error;
00430 }
00431 
00432 /*****************************************************************************/
00433 /**
00434  * \brief Attach data dataspace
00435  * \ingroup internal
00436  * 
00437  * \param socket         Socket descriptor
00438  * \param data_ds        Data dataspace
00439  *      
00440  * \return 0 on success, error code otherwise:
00441  *         - -L4_EINVAL  invalid dataspace
00442  *         - -L4_EPERM   no permissions to access dataspace
00443  *         - -L4_EIPC    IPC error calling dataspace manager
00444  *         - -L4_ENOMEM  out of memory attaching dataspace
00445  *         - -L4_ENOMAP  no map area available to attach dataspace
00446  */
00447 /*****************************************************************************/ 
00448 int 
00449 dsi_set_data_area(dsi_socket_t * socket, l4dm_dataspace_t data_ds)
00450 {
00451   int ret,i;
00452   l4_size_t size;
00453   void * map;
00454   l4dm_dataspace_t ds;
00455   l4_uint32_t flags;
00456 
00457   /* sanity checks */
00458   Assert(socket != NULL);
00459 
00460   if (IS_RECEIVE_SOCKET(socket) && (socket->flags & DSI_SOCKET_COPY))
00461     {
00462       /* we copy the data, allocate new dataspace */
00463       ret = l4dm_mem_size(&data_ds,&size);
00464       if (ret < 0)
00465         {
00466           LOG_Error("DSI: get dataspace size failed: %s (%d)",
00467                     l4env_errstr(ret), ret);
00468           return -L4_EINVAL;
00469         }
00470 
00471       LOGdL(DEBUG_DATA_DS,"allocate data_ds, size %u",size);
00472 
00473       /* check dataspace manager */
00474       if (l4_thread_equal(dsi_dm_id,L4_INVALID_ID))
00475         {
00476           if (__get_dm_id())
00477             return -DSI_ENODSM;
00478         }
00479       ASSERT(!l4_thread_equal(dsi_dm_id,L4_INVALID_ID));
00480 
00481       /* allocate dataspace */
00482       if (l4dm_mem_ds_is_contiguous(&data_ds))
00483         ret = l4dm_mem_open(dsi_dm_id,size,0,L4DM_CONTIGUOUS,"DSI data",&ds);
00484       else
00485         ret = l4dm_mem_open(dsi_dm_id,size,0,0,"DSI data",&ds);
00486       if (ret < 0)
00487         {
00488           LOG_Error("DSI: dataspace allocation failed: %s (%d)!",
00489                     l4env_errstr(ret), ret); 
00490           return ret;
00491         }
00492 
00493       /* we must release this dataspace on close */
00494       socket->flags |= DSI_SOCKET_FREE_DATA;
00495     }
00496   else
00497     {
00498       /* check dataspace */
00499       ret = l4dm_check_rights(&data_ds,L4DM_RW);
00500       if (ret < 0)
00501         {
00502           LOG_Error("DSI: invalid data dataspace: %s (%d)!",
00503                     l4env_errstr(ret), ret);
00504           return ret;
00505         }
00506       ds = data_ds;
00507     }
00508 
00509   LOGdL(DEBUG_DATA_DS,"attaching data area, ds %d at "l4util_idfmt,
00510         data_ds.id,l4util_idstr(data_ds.manager));
00511   
00512   /* get dataspace size */
00513   ret = l4dm_mem_size(&ds,&size);
00514   if (ret < 0)
00515     {
00516       LOG_Error("DSI: get dataspace size failed: %s (%d)", 
00517                 l4env_errstr(ret), ret);
00518       return -L4_EINVAL;
00519     }
00520 
00521   /* Calculate the alignment of the map area. We attach the map area to 
00522    * an address which is aligned to the next larger 2^n size of the dataspace
00523    * size. We need this to be able to specify the map area as a receive
00524    * fpage if we must map the data area from the remote component.
00525    * (Actually, we alignment is done by the region mapper, but we need 
00526    * the aligment to specify the receive fpage). 
00527    */
00528   i = 0;
00529   while (size > (1 << i)) 
00530     i++;
00531   
00532   flags = L4RM_LOG2_ALIGNED | L4RM_LOG2_ALLOC;
00533   if (!(socket->flags & DSI_SOCKET_MAP))
00534     {
00535       flags |= L4RM_MAP;
00536       if (IS_RECEIVE_SOCKET(socket) && !(socket->flags & DSI_SOCKET_COPY))
00537         flags |= L4DM_RO;
00538       else
00539         flags |= L4DM_RW;
00540     }
00541   
00542   /* attach dataspace */
00543   if (dds_map_area != -1)
00544     ret = l4rm_area_attach(&ds,dds_map_area,size,0,flags,&map);
00545   else
00546     ret = l4rm_attach(&ds,size,0,flags,&map);
00547   if (ret)
00548     {
00549       LOG_Error("DSI: attach data dataspace failed: %s (%d)",
00550                 l4env_errstr(ret), ret);
00551       return ret;
00552     }
00553   
00554   /* setup socket descriptor */
00555   socket->data_ds = ds;
00556   socket->data_area = map;
00557   socket->data_size = size;
00558   socket->data_map_size = i;
00559   socket->next_buf = map;
00560 
00561   LOGdL(DEBUG_DATA_DS, "attached data ds to addr 0x%08lx", (l4_addr_t)map);
00562 
00563   /* done */
00564   return 0;
00565 }
00566 
00567 /*****************************************************************************/
00568 /**
00569  * \brief Detach data dataspace.
00570  * 
00571  * \param  socket        Socket descriptor
00572  *      
00573  * \return 0 on success, error code otherwise.
00574  */
00575 /*****************************************************************************/ 
00576 int 
00577 dsi_release_data_area(dsi_socket_t * socket)
00578 {
00579   int ret;
00580   int error = 0;
00581 
00582   LOGdL(DEBUG_DATA_DS, "detaching data area (ds %d at "l4util_idfmt")",
00583         socket->data_ds.id, l4util_idstr(socket->data_ds.manager));
00584 
00585   /* detach data dataspace */
00586   ret = l4rm_detach(socket->data_area);
00587   if (ret < 0)
00588     {
00589       LOG_Error("DSI: detach data dataspace failed: %s (%d)",
00590                 l4env_errstr(ret), ret);
00591       error = ret;
00592     }
00593 
00594   if (socket->flags & DSI_SOCKET_FREE_DATA)
00595     {
00596       /* close dataspace */
00597       ret = l4dm_close(&socket->data_ds);
00598       if (ret < 0)
00599         {
00600           LOG_Error("DSI: close data dataspace failed: %s (%d)",
00601                     l4env_errstr(ret), ret);
00602           error = ret;
00603         }
00604     }
00605 
00606   /* done */
00607   return error;
00608 }
00609 
00610 /*****************************************************************************/
00611 /**
00612  * \brief Setup dataspace handling.
00613  */
00614 /*****************************************************************************/ 
00615 void
00616 dsi_init_dataspaces(void)
00617 {
00618   int ret;
00619 
00620 #if DSI_USE_CDS_AREA
00621   // reserve map area for control dataspaces
00622   ret = l4rm_area_reserve_region(DSI_CDS_MAP_START,DSI_CDS_MAP_SIZE,
00623                                  0,&cds_map_area);
00624   if (ret)
00625     {
00626       LOG_Error("DSI: failed to reserve map area for control dataspaces: "
00627                 "%s (%d)", l4env_errstr(ret), ret);
00628       cds_map_area = -1;
00629     }
00630 #endif
00631 
00632 #if DSI_USE_DDS_AREA
00633   // reserve map area for data dataspaces
00634   ret = l4rm_area_reserve_region(DSI_DDS_MAP_START,DSI_DDS_MAP_SIZE,
00635                                  0,&dds_map_area);
00636   if (ret)
00637     {
00638       LOG_Error("DSI: failed to reserve map area for data dataspaces: "
00639                 "%s (%d)", l4env_errstr(ret), ret);
00640       dds_map_area = -1;
00641     }
00642 #endif
00643 }
00644 
00645 /*****************************************************************************
00646  * API functions
00647  *****************************************************************************/
00648 
00649 /*****************************************************************************/
00650 /**
00651  * \brief  Share socket dataspaces
00652  * \ingroup socket
00653  * 
00654  * \param  socket        Socket descriptor
00655  * \param  client        Client thread id
00656  *      
00657  * \return 0 on success (allowed read-write access for client), 
00658  *         error code otherwise:
00659  *         - \c -L4_EINVAL invalid socket descriptor
00660  *         - \c -L4_EPERM  operation not allowed
00661  *         - \c -L4_EIPC   error calling dataspace manager
00662  */
00663 /*****************************************************************************/ 
00664 int
00665 dsi_socket_share_ds(dsi_socket_t * socket, l4_threadid_t client)
00666 {
00667   int ret;
00668   int error = 0;
00669 
00670   /* check socket descriptor */
00671   if (!dsi_is_valid_socket(socket))
00672     return -L4_EINVAL;
00673 
00674   if (!l4dm_is_invalid_ds(socket->data_ds))
00675     {
00676       ret = l4dm_share(&socket->data_ds,client,L4DM_RW);
00677       if (ret < 0)
00678         error = ret;
00679     }
00680 
00681   if (!l4dm_is_invalid_ds(socket->ctrl_ds))
00682     {
00683       ret = l4dm_share(&socket->ctrl_ds,client,L4DM_RW);
00684       if (ret < 0)
00685         error = ret;
00686     }
00687 
00688   /* done */
00689   return error;
00690 }
00691 
00692 /*****************************************************************************/
00693 /**
00694  * \brief  Set new dataspace manager.
00695  * \ingroup general
00696  * 
00697  * \param  id            dataspace manager id
00698  */
00699 /*****************************************************************************/ 
00700 void 
00701 dsi_ds_set_dataspace_manager(l4_threadid_t id)
00702 {
00703   /* set dataspace manager id */
00704   dsi_dm_id = id;
00705 }
00706 
00707 /*****************************************************************************/
00708 /**
00709  * \brief   Setup control dataspace
00710  * \ingroup general
00711  * 
00712  * \param   ds           Dataspace id
00713  * \param   cfg          Stream configuration
00714  *      
00715  * \return  0 on success, error code otherwise:
00716  *          - -#L4_EINVAL invalid dataspace
00717  *
00718  * Setup control dataspace without a socket, it can be used by an application 
00719  * to create a control dataspace which the application passed to both the
00720  * send and receive component
00721  */
00722 /*****************************************************************************/ 
00723 int 
00724 dsi_ds_setup_ctrl_dataspace(l4dm_dataspace_t * ds, dsi_stream_cfg_t cfg)
00725 {
00726   l4_size_t size = __get_ctrl_ds_size(cfg);
00727   l4_size_t ds_size;
00728   int ret;
00729   void * map_addr;
00730 
00731   /* check dataspace size */
00732   ret = l4dm_mem_size(ds, &ds_size);
00733   if (ret < 0)
00734     return ret;
00735 
00736   if (ds_size < size)
00737     {
00738       LOG_Error("dataspace too small!");
00739       return -L4_EINVAL;
00740     }
00741 
00742   /* map dataspace */
00743   ret = l4rm_attach(ds, size, 0, L4DM_RW | L4RM_MAP, &map_addr);
00744   if (ret < 0)
00745     {
00746       LOG_Error("attach dataspace failed: %s (%d)!", l4env_errstr(ret), ret);
00747       return ret;
00748     }
00749 
00750   /* init control dataspace dataspace */
00751   __init_ctrl_ds((l4_addr_t)map_addr, size, cfg);
00752 
00753   /* done, detach dataspace */
00754   l4rm_detach(map_addr);
00755 
00756   return 0;
00757 }
00758 
00759 /*****************************************************************************/
00760 /**
00761  * \brief   Create control dataspace
00762  * \ingroup general
00763  * 
00764  * \param   cfg          Stream configuration
00765  * \retval  ds           Control dataspace id
00766  *      
00767  * \return  0 on success, error code otherwise:
00768  *          - -#L4_ENOMEM  dataspace allocation failed
00769  */
00770 /*****************************************************************************/ 
00771 int
00772 dsi_ds_create_ctrl_dataspace(dsi_stream_cfg_t cfg, l4dm_dataspace_t * ds)
00773 {
00774   l4_size_t size = __get_ctrl_ds_size(cfg);
00775   l4_addr_t map_addr;
00776 
00777   /* allocate dataspace */
00778   map_addr = (l4_addr_t)l4dm_mem_ds_allocate(size, L4DM_RW | L4RM_MAP, ds);
00779   if (map_addr == 0)
00780     return -L4_ENOMEM;
00781 
00782   /* init control dataspace */
00783   __init_ctrl_ds((l4_addr_t)map_addr, size, cfg);
00784 
00785   /* done, detach dataspace */
00786   l4rm_detach((void *)map_addr);
00787  
00788   /* done */
00789   return 0;
00790 }

Generated on Wed Apr 11 06:40:13 2012 for DSI - Drops Streaming Interface by  doxygen 1.5.6