home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Examples / UNIX / LKSOutOfLineData / KernelServer / mydriver_main.c < prev    next >
Encoding:
Text File  |  1995-02-10  |  5.3 KB  |  179 lines

  1. /* mydriver_main.c:  major functions of mydriver */
  2.  
  3. #import <kernserv/kern_server_types.h>
  4. #import <kernserv/prototypes.h>
  5. #import <ansi/string.h>
  6. #import "../Library/mydefs.h"
  7.  
  8. kern_server_t instance;
  9.  
  10. /* Pointer to hold local data in the kernel_task's vm */
  11. static user_data_t local_data;
  12.  
  13. /* mydriver_init:  Called when mydriver is loaded. */
  14. void mydriver_init(void)
  15. {
  16.     kern_return_t r;
  17.     port_t kernel_task = kern_serv_kernel_task_port();    
  18.  
  19.     //
  20.     // Get a page of publically readable vm to be used to access the mig
  21.     // messages out of line data.  Also used to hold data across import
  22.     // and export calls.
  23.     //
  24.     r = vm_allocate
  25.     (kernel_task, (vm_address_t *) &local_data, page_size, TRUE);
  26.     if (r != KERN_SUCCESS)
  27.     {
  28.     printf("Call to vm_allocate failed %d\n", r);
  29.     local_data = NULL;
  30.     }
  31.  
  32.     //
  33.     // Clear the newly acquired memory
  34.     //
  35.     memset(local_data, '\0', page_size);
  36.     
  37.     printf("My driver loaded\n");
  38. }
  39.  
  40.  
  41. /* mydriver_signoff:  Called when mydriver is unloaded. */
  42. void mydriver_signoff(void)
  43. {
  44.     kern_return_t r;
  45.     port_t kernel_task = kern_serv_kernel_task_port();    
  46.  
  47.     // Deallocate the kernel vm's local_data buffer
  48.     r = vm_deallocate(kernel_task, (vm_address_t) local_data, page_size);
  49.     if (r != KERN_SUCCESS)
  50.     {
  51.     printf("Call to vm_deallocate failed %d\n", r);
  52.     local_data = NULL;
  53.     }
  54.     
  55.     printf("My driver unloaded\n\n");
  56. }
  57.  
  58. /* mydriver_import:  Called by mydriver_server, which was created by MiG. */
  59. kern_return_t mydriver_import
  60.     (port_t server, in_user_data_t user_data, unsigned int length)
  61. {
  62.     kern_return_t r;
  63.     user_data_t tmp;
  64.     port_t kernel_task = kern_serv_kernel_task_port();    
  65.  
  66.     if (!local_data)
  67.     return KERN_FAILURE;
  68.  
  69.     //
  70.     // Warning:  Loadable kernel servers run outside of the kernel task,
  71.     // even though they use the kernel address map.
  72.     //
  73.     // This means that we have to get the task_self's user_data into the
  74.     // kernel's vm.  To do this we have to, counterintuitively, write the
  75.     // received data into our previously acquired vm page (kernel_task).
  76.     //
  77.     r = vm_write((vm_task_t) kernel_task, (vm_address_t) local_data,
  78.     (pointer_t) user_data, page_size);
  79.  
  80.     if (r == KERN_SUCCESS)
  81.     {
  82.     tmp = local_data;
  83.     printf("\nTrying to access data.\n");
  84.     printf("First  data element is: %c\n", *tmp++);
  85.     printf("Second data element is: %c\n", *tmp++);
  86.     printf("Third  data element is: %c\n", *tmp++);
  87.     printf("Fourth data element is: %c\n", *tmp++);
  88.     printf("Fifth  data element is: %c\n", *tmp++);
  89.     
  90.     printf("Contents of data are: %s\n", local_data);
  91.     }
  92.     else switch(r)
  93.     {
  94.     case KERN_INVALID_ARGUMENT:
  95.         printf("vm_write: KERN_INVALID_ARGUMENT %d\n", r);
  96.         break;
  97.     case KERN_PROTECTION_FAILURE:
  98.         printf("vm_write: KERN_PROTECTION_FAILURE %d\n", r);
  99.         break;
  100.     case KERN_INVALID_ADDRESS:
  101.         printf("vm_write: KERN_INVALID_ADDRESS %d\n", r);
  102.         break;
  103.     default:
  104.         printf("Call to vm_write failed %d\n", r);
  105.     }
  106.     
  107.     // 
  108.     // Remove the out_of_band data from the kernel server task's vm.
  109.     // Otherwise we would have a memory leak across the mach message interface.
  110.     //
  111.     r = vm_deallocate(task_self(), (vm_address_t) user_data, page_size);
  112.     if (r != KERN_SUCCESS)
  113.     printf("Call to vm_deallocate user_data failed %d\n", r);
  114.     
  115.     return r;
  116. }    
  117.  
  118. /* mydriver_export:  Called by mydriver_server, which was created by MiG. */
  119. kern_return_t mydriver_export
  120.     (port_t server, out_user_data_t *user_data, unsigned int *length)
  121. {
  122.     kern_return_t r;
  123.     port_t kernel_task = kern_serv_kernel_task_port();
  124.     unsigned int tmp;
  125.     
  126.     if (!local_data)
  127.     {
  128.     // Get some vm for the mig out of band data to deallocate
  129.     (void) vm_allocate
  130.         (task_self(), (vm_address_t *) user_data, page_size, TRUE);
  131.     
  132.     return KERN_FAILURE;
  133.     }
  134.     
  135.     // Tack an ACK on the end of the imported data
  136.     strcat(local_data, "ACK");
  137.     *length = strlen(local_data) + 1;
  138.     printf("\nData is: %s\n", local_data);
  139.  
  140.     //
  141.     // Warning:  Loadable kernel servers run outside of the kernel task,
  142.     // even though they use the kernel address map.
  143.     //
  144.     // This means that we have to load the task_self's user_data pointer from
  145.     // the kernel's vm.  To do this we have to, counterintuitively again,
  146.     // vm_read the local_data into our task's vm, NB we do not have to
  147.     // previously allocate the vm.  The vm_read data will be deallocated
  148.     // automatically by the mach message system as the type was declared
  149.     // with dealloc on the mig type.
  150.     //
  151.     r = vm_read((vm_task_t) kernel_task, (vm_address_t) local_data,
  152.         page_size, (pointer_t *) user_data, &tmp);
  153.     if (r != KERN_SUCCESS)
  154.     {
  155.     // Get some vm for the mig out of band data to deallocate
  156.     (void) vm_allocate
  157.         (task_self(), (vm_address_t *) user_data, page_size, TRUE);
  158.     
  159.     switch (r)
  160.     {
  161.     case KERN_INVALID_ARGUMENT:
  162.         printf("vm_read: KERN_INVALID_ARGUMENT %d\n", r);    break;
  163.     case KERN_NO_SPACE:
  164.         printf("vm_read: KERN_NO_SPACE %d\n", r);        break;
  165.     case KERN_PROTECTION_FAILURE:
  166.         printf("vm_read: KERN_PROTECTION_FAILURE %d\n", r);    break;
  167.     case KERN_INVALID_ADDRESS:
  168.         printf("vm_read: KERN_INVALID_ADDRESS %d\n", r);    break;
  169.     default: printf("Call to vm_read failed: %d\n", r);        break;
  170.     }
  171.     }
  172.  
  173.     //
  174.     // No matter what path we take through this function we always have some
  175.     // disposable vm in task_self's memory for dealloc-ing.
  176.     //
  177.     return r;
  178. }
  179.