/[rtmk]/rtmk/ipc-kmsg.c
ViewVC logotype

Diff of /rtmk/ipc-kmsg.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by jrydberg, Thu Feb 21 20:14:42 2002 UTC revision 1.11 by jrydberg, Sat Feb 23 01:41:01 2002 UTC
# Line 30  Foundation, Inc., 59 Temple Place - Suit Line 30  Foundation, Inc., 59 Temple Place - Suit
30    
31  #include "ipc-kmsg.h"  #include "ipc-kmsg.h"
32    
33    #ifndef WORD_ALIGN
34    # define WORD_ALIGN(X) (((X) + 3) & ~3)
35    #endif
36    
37  #define KERNEL_MSG_SIZE (256-4)  #define KERNEL_MSG_SIZE (256-4)
38    
39  static struct kmem_cache *kmsg_cache;  static struct kmem_cache *kmsg_cache;
40    
41  /* Initialize kernel messages.  */  /* Initialize kernel messages.  */
   
42  void  void
43  ipc_kmsg_init (void)  ipc_kmsg_init (void)
44  {  {
# Line 45  ipc_kmsg_init (void) Line 48  ipc_kmsg_init (void)
48    
49  /* Allocate a new kernel message with SIZE bytes payload.    /* Allocate a new kernel message with SIZE bytes payload.  
50     SIZE includes the size of the header.  */     SIZE includes the size of the header.  */
   
51  struct ipc_kmsg *  struct ipc_kmsg *
52  ipc_kmsg_alloc (vm_size_t size)  ipc_kmsg_alloc (vm_size_t size)
53  {  {
# Line 78  ipc_kmsg_alloc (vm_size_t size) Line 80  ipc_kmsg_alloc (vm_size_t size)
80  }  }
81    
82  /* Free a kernel message allocated with ipc_kmsg_alloc.  */  /* Free a kernel message allocated with ipc_kmsg_alloc.  */
   
83  void  void
84  ipc_kmsg_free (struct ipc_kmsg *kmsg)  ipc_kmsg_free (struct ipc_kmsg *kmsg)
85  {  {
# Line 161  copyin_header (struct task *task, struct Line 162  copyin_header (struct task *task, struct
162    return KERN_SUCCESS;    return KERN_SUCCESS;
163  }  }
164    
165  #ifndef WORD_ALIGN  /* Convert message stored in KMSG to intermedate format where port
166  # define WORD_ALIGN(X) (((X) + 3) & ~3)     names are resolved to ipc_port structures and out-of-line data
167  #endif     in mapped into kernel address space.  */
   
168  kern_return_t  kern_return_t
169  copyin_body (struct task *task, struct ipc_kmsg *kmsg)  copyin_body (struct task *task, struct ipc_kmsg *kmsg)
170  {  {
171      struct rtmk_msg_type_long *type_long;
172    struct rtmk_msg_type *type;    struct rtmk_msg_type *type;
173    struct ipc_entry *entry;    struct ipc_entry *entry;
174    vm_offset_t start, end;    vm_offset_t start, end;
175    kern_return_t kr;    kern_return_t kr;
176    
177    start = (vm_offset_t) (&kmsg->header + 1);    start = (vm_offset_t)  (&kmsg->header + 1);
178    end   = ((vm_offset_t) (&kmsg->header)) + kmsg->header.msgh_length;    end   = ((vm_offset_t) (&kmsg->header)) + kmsg->header.msgh_length;
179    
180    /* Loop through all type elements of the message body.  */    /* Loop through all type elements of the message body.  */
181    
182    while (start < end)    while (start < end)
183      {      {
184          unsigned int header_size, number, length, size, i;
185          vm_offset_t data_ptr;
186    
187          /* If we we have a long format message type header we
188             get length and number fields from long structure. */
189        type = (struct rtmk_msg_type *) start;        type = (struct rtmk_msg_type *) start;
190                size = type->msgt_length;
191    
192          if (LIKELY (! type->msgt_long))
193            {
194              header_size = sizeof (struct rtmk_msg_type);
195              number = type->msgt_number;
196            }
197          else
198            {
199              type_long = (struct rtmk_msg_type_long *) type;
200              header_size = sizeof (struct rtmk_msg_type_long);
201              number = type_long->msgtl_number;
202            }
203    
204          /* DATA_PTR points to where the inline data begins.  */
205          data_ptr = ((vm_offset_t) type) + header_size;
206    
207          /* If TYPE->MSGT_TYPE specifys any port type we must
208             handle right manipulation.  This is a pretty common case.  */
209        if (RTMK_MSG_TYPE_PORT_ANY (type->msgt_type))        if (RTMK_MSG_TYPE_PORT_ANY (type->msgt_type))
210          {          {
211            rtmk_port_t port_name;            rtmk_port_t *port_name;
212            struct ipc_port *port;            struct ipc_port *port;
213                        
214            /* ??? ports can not be in out-of-line memory?  */            /* ??? ports can not be in out-of-line memory?  */
215            assert (type->msgt_inline == true);            assert (type->msgt_inline == true);
216              port_name = (rtmk_port_t *) data_ptr;
217                        
218            /* Get port name (located after type structure).   */            /* Loop through all elements and take actions upon them.  */
219            port_name = *(rtmk_port_t *) (type + 1);            for (i = 0; i < number; i++)
             
           /* ??? if PORT_NAME is null we do nothing.   */  
           if (port_name)  
220              {              {
221                kr = ipc_object_lookup (task->ipc_object, port_name, &entry);                if (port_name [i])
222                if (kr != KERN_SUCCESS)                  {
223                  return kr;                    kr = ipc_object_lookup (task->ipc_object, port_name [i],
224                                                            & entry);
225                port = entry->ie_port;                    if (kr != KERN_SUCCESS)
226              }                      return kr;
227            else                  
228              port = 0;                    port = entry->ie_port;
229                    }
230                  else
231                    port = 0;
232                        
233            /* Store pointer to port structure in place for port name.  */                /* Store pointer to port structure in place for port name.  */
234                  port_name [i] = (rtmk_port_t) port;
235            *(struct ipc_port **) (type + 1) = port;              }
           start = start + sizeof *type + (vm_offset_t) (type->msgt_length);  
236          }          }
237                
238        /* Out-of-line memory.  ??? not supported yet, just skip it.  */        /* Out-of-line memory.  ??? not supported yet, just skip it.  */
         
239        else if (type->msgt_inline == false)        else if (type->msgt_inline == false)
240          {          {
241            /* ??? WORD_SIZE */            /* ??? handle OOL memory here.  */
           start = start + sizeof *type + sizeof (long);  
242          }          }
         
       /* For normal inline memory we just step over the chunk.   */  
243    
244          /* Calulcat length of inline data and skip over it.   */
245          length = ((number * size) + 7) >> 3;
246          if (LIKELY (type->msgt_inline))
247            start = WORD_ALIGN (data_ptr + length);
248        else        else
249          start = start + sizeof *type + (type->msgt_length);          start = data_ptr + sizeof (rtmk_port_t *); /* ??? ptr */
   
       /* Start of message type structure should always be word aligned.  */  
   
       start = WORD_ALIGN (start);  
250      }      }
   
251    return KERN_SUCCESS;    return KERN_SUCCESS;
252  }  }
253    
254    /* Convert message stored in KMSG from intermedate format to format
255       that can be directly copied to user-land task.  Out-of-line data
256       is mapped in TASK's addres space, and ports are resolved.  */
257  static kern_return_t  static kern_return_t
258  copyout_body (struct task *task, struct ipc_kmsg *kmsg)  copyout_body (struct task *task, struct ipc_kmsg *kmsg)
259  {  {
260      struct rtmk_msg_type_long *type_long;
261    struct rtmk_msg_type *type;    struct rtmk_msg_type *type;
262    vm_offset_t start, end;    vm_offset_t start, end;
263    kern_return_t kr;    kern_return_t kr;
264    
265    start = (vm_offset_t) (&kmsg->header + 1);    start = (vm_offset_t)  (&kmsg->header + 1);
266    end   = ((vm_offset_t) (&kmsg->header)) + kmsg->header.msgh_length;    end   = ((vm_offset_t) (&kmsg->header)) + kmsg->header.msgh_length;
267    
268    /* Loop through all type elements of the message body.  */    /* Loop through all type elements of the message body.  */
269    
270    while (start < end)    while (start < end)
271      {      {
272          unsigned int header_size, number, length, size, i;
273          vm_offset_t data_ptr;
274    
275          /* If we we have a long format message type header we
276             get length and number fields from long structure. */
277        type = (struct rtmk_msg_type *) start;        type = (struct rtmk_msg_type *) start;
278                size = type->msgt_length;
279    
280          if (LIKELY (! type->msgt_long))
281            {
282              header_size = sizeof (struct rtmk_msg_type);
283              number = type->msgt_number;
284            }
285          else
286            {
287              type_long = (struct rtmk_msg_type_long *) type;
288              header_size = sizeof (struct rtmk_msg_type_long);
289              number = type_long->msgtl_number;
290            }
291    
292          /* DATA_PTR points to where the inline data begins.  */
293          data_ptr = ((vm_offset_t) type) + header_size;
294    
295          /* If TYPE->MSGT_TYPE specifys any port type we must
296             handle right manipulation.  This is a pretty common case.  */
297        if (RTMK_MSG_TYPE_PORT_ANY (type->msgt_type))        if (RTMK_MSG_TYPE_PORT_ANY (type->msgt_type))
298          {          {
299            rtmk_port_t port_name;            struct ipc_port **port;
300            struct ipc_port *port;            rtmk_port_t *port_name;
301                        
302            /* ??? ports can not be in out-of-line memory?  */            /* ??? ports can not be in out-of-line memory?  */
303            assert (type->msgt_inline == true);            assert (type->msgt_inline == true);
304                        
305            /* Get port name (located after type structure).   */            port_name = (rtmk_port_t *) data_ptr;
306            port = *(struct ipc_port **) (type + 1);            port      = (struct ipc_port **) data_ptr;
             
           /* ??? if PORT_NAME is null we do nothing.   */  
           if (port)  
             {  
               kr = ipc_object_copyout (task->ipc_object, port, type->msgt_type,  
                                        &port_name);  
               if (kr != KERN_SUCCESS)  
                 return kr;  
             }  
           else  
             port_name = RTMK_PORT_NULL;  
             
           /* Store pointer to port structure in place for port name.  */  
307    
308            *(rtmk_port_t *) (type + 1) = port_name;            /* Loop through all elements and take actions upon them.  */
309            start = start + sizeof *type + (vm_offset_t) (type->msgt_length);            for (i = 0; i < number; i++)
310                {    
311                  if (port [i])
312                    {
313                      kr = ipc_object_copyout (task->ipc_object, port [i],
314                                               type->msgt_type, & port_name [i]);
315                      if (kr != KERN_SUCCESS)
316                        return kr;
317                    }
318                  else
319                    port_name [i] = RTMK_PORT_NULL;
320                }
321          }          }
322                
323        /* Out-of-line memory.  ??? not supported yet, just skip it.  */        /* Out-of-line memory.  ??? not supported yet, just skip it.  */
         
324        else if (type->msgt_inline == false)        else if (type->msgt_inline == false)
325          {          {
326            /* ??? WORD_SIZE */            /* ??? */
           start = start + sizeof *type + sizeof (long);  
327          }          }
         
       /* For normal inline memory we just step over the chunk.   */  
328    
329          /* Calulcat length of inline data and skip over it.   */
330          length = ((number * size) + 7) >> 3;
331          if (LIKELY (type->msgt_inline))
332            start = WORD_ALIGN (data_ptr + length);
333        else        else
334          start = start + sizeof *type + (type->msgt_length);          start = data_ptr + sizeof (rtmk_port_t *); /* ??? ptr */
   
       /* Start of message type structure should always be word aligned.  */  
   
       start = WORD_ALIGN (start);  
335      }      }
   
336    return KERN_SUCCESS;    return KERN_SUCCESS;
337  }  }
338    

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26