Subversion Repositories HelenOS

Rev

Rev 4416 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2007 Josef Cejka
  3.  * Copyright (c) 2009 Jiri Svoboda
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *
  10.  * - Redistributions of source code must retain the above copyright
  11.  *   notice, this list of conditions and the following disclaimer.
  12.  * - Redistributions in binary form must reproduce the above copyright
  13.  *   notice, this list of conditions and the following disclaimer in the
  14.  *   documentation and/or other materials provided with the distribution.
  15.  * - The name of the author may not be used to endorse or promote products
  16.  *   derived from this software without specific prior written permission.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  19.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  20.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  22.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28.  */
  29.  
  30. #include <string.h>
  31. #include <ipc/ipc.h>
  32. #include <ipc/services.h>
  33. #include <ipc/devmap.h>
  34. #include <devmap.h>
  35. #include <async.h>
  36. #include <errno.h>
  37.  
  38. static int devmap_phone_driver = -1;
  39. static int devmap_phone_client = -1;
  40.  
  41. /** Get phone to device mapper task. */
  42. int devmap_get_phone(devmap_interface_t iface, unsigned int flags)
  43. {
  44.     switch (iface) {
  45.     case DEVMAP_DRIVER:
  46.         if (devmap_phone_driver >= 0)
  47.             return devmap_phone_driver;
  48.        
  49.         if (flags & IPC_FLAG_BLOCKING)
  50.             devmap_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
  51.                 SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
  52.         else
  53.             devmap_phone_driver = ipc_connect_me_to(PHONE_NS,
  54.                 SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
  55.        
  56.         return devmap_phone_driver;
  57.     case DEVMAP_CLIENT:
  58.         if (devmap_phone_client >= 0)
  59.             return devmap_phone_client;
  60.        
  61.         if (flags & IPC_FLAG_BLOCKING)
  62.             devmap_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
  63.                 SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
  64.         else
  65.             devmap_phone_client = ipc_connect_me_to(PHONE_NS,
  66.                 SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
  67.        
  68.         return devmap_phone_client;
  69.     default:
  70.         return -1;
  71.     }
  72. }
  73.  
  74. void devmap_hangup_phone(devmap_interface_t iface)
  75. {
  76.     switch (iface) {
  77.     case DEVMAP_DRIVER:
  78.         if (devmap_phone_driver >= 0) {
  79.             ipc_hangup(devmap_phone_driver);
  80.             devmap_phone_driver = -1;
  81.         }
  82.         break;
  83.     case DEVMAP_CLIENT:
  84.         if (devmap_phone_client >= 0) {
  85.             ipc_hangup(devmap_phone_client);
  86.             devmap_phone_client = -1;
  87.         }
  88.         break;
  89.     default:
  90.         break;
  91.     }
  92. }
  93.  
  94. /** Register new driver with devmap. */
  95. int devmap_driver_register(const char *name, async_client_conn_t conn)
  96. {
  97.     int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
  98.    
  99.     if (phone < 0)
  100.         return phone;
  101.    
  102.     ipc_call_t answer;
  103.     aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
  104.    
  105.     ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
  106.    
  107.     if (retval != EOK) {
  108.         async_wait_for(req, NULL);
  109.         return -1;
  110.     }
  111.    
  112.     async_set_client_connection(conn);
  113.    
  114.     ipcarg_t callback_phonehash;
  115.     ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
  116.     async_wait_for(req, &retval);
  117.    
  118.     return retval;
  119. }
  120.  
  121. /** Register new device.
  122.  *
  123.  * @param name   Device name.
  124.  * @param handle Output: Handle to the created instance of device.
  125.  *
  126.  */
  127. int devmap_device_register(const char *name, dev_handle_t *handle)
  128. {
  129.     int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
  130.    
  131.     if (phone < 0)
  132.         return phone;
  133.    
  134.     ipc_call_t answer;
  135.     aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
  136.         &answer);
  137.    
  138.     ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
  139.    
  140.     if (retval != EOK) {
  141.         async_wait_for(req, NULL);
  142.         return retval;
  143.     }
  144.    
  145.     async_wait_for(req, &retval);
  146.    
  147.     if (retval != EOK) {
  148.         if (handle != NULL)
  149.             *handle = -1;
  150.         return retval;
  151.     }
  152.    
  153.     if (handle != NULL)
  154.         *handle = (dev_handle_t) IPC_GET_ARG1(answer);
  155.    
  156.     return retval;
  157. }
  158.  
  159. int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
  160. {
  161.     int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
  162.    
  163.     if (phone < 0)
  164.         return phone;
  165.    
  166.     ipc_call_t answer;
  167.     aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
  168.         &answer);
  169.    
  170.     ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
  171.    
  172.     if (retval != EOK) {
  173.         async_wait_for(req, NULL);
  174.         return retval;
  175.     }
  176.    
  177.     async_wait_for(req, &retval);
  178.    
  179.     if (retval != EOK) {
  180.         if (handle != NULL)
  181.             *handle = -1;
  182.         return retval;
  183.     }
  184.    
  185.     if (handle != NULL)
  186.         *handle = (dev_handle_t) IPC_GET_ARG1(answer);
  187.    
  188.     return retval;
  189. }
  190.  
  191. int devmap_device_connect(dev_handle_t handle, unsigned int flags)
  192. {
  193.     int phone;
  194.    
  195.     if (flags & IPC_FLAG_BLOCKING) {
  196.         phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
  197.             DEVMAP_CONNECT_TO_DEVICE, handle);
  198.     } else {
  199.         phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
  200.             DEVMAP_CONNECT_TO_DEVICE, handle);
  201.     }
  202.    
  203.     return phone;
  204. }
  205.  
  206. ipcarg_t devmap_device_get_count(void)
  207. {
  208.     int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
  209.    
  210.     if (phone < 0)
  211.         return 0;
  212.    
  213.     ipcarg_t count;
  214.     int retval = ipc_call_sync_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
  215.     if (retval != EOK)
  216.         return 0;
  217.    
  218.     return count;
  219. }
  220.  
  221. ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
  222. {
  223.     int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
  224.    
  225.     if (phone < 0)
  226.         return 0;
  227.    
  228.     ipc_call_t answer;
  229.     aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
  230.    
  231.     ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
  232.    
  233.     if (retval != EOK) {
  234.         async_wait_for(req, NULL);
  235.         return 0;
  236.     }
  237.    
  238.     async_wait_for(req, &retval);
  239.    
  240.     if (retval != EOK)
  241.         return 0;
  242.    
  243.     return IPC_GET_ARG1(answer);
  244. }
  245.