Subversion Repositories HelenOS

Rev

Rev 4549 | 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.     async_serialize_start();
  103.    
  104.     ipc_call_t answer;
  105.     aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
  106.    
  107.     ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
  108.    
  109.     if (retval != EOK) {
  110.         async_wait_for(req, NULL);
  111.         async_serialize_end();
  112.         return -1;
  113.     }
  114.    
  115.     async_set_client_connection(conn);
  116.    
  117.     ipcarg_t callback_phonehash;
  118.     ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
  119.     async_wait_for(req, &retval);
  120.    
  121.     async_serialize_end();
  122.    
  123.     return retval;
  124. }
  125.  
  126. /** Register new device.
  127.  *
  128.  * @param name   Device name.
  129.  * @param handle Output: Handle to the created instance of device.
  130.  *
  131.  */
  132. int devmap_device_register(const char *name, dev_handle_t *handle)
  133. {
  134.     int phone = devmap_get_phone(DEVMAP_DRIVER, IPC_FLAG_BLOCKING);
  135.    
  136.     if (phone < 0)
  137.         return phone;
  138.    
  139.     async_serialize_start();
  140.    
  141.     ipc_call_t answer;
  142.     aid_t req = async_send_2(phone, DEVMAP_DEVICE_REGISTER, 0, 0,
  143.         &answer);
  144.    
  145.     ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
  146.    
  147.     if (retval != EOK) {
  148.         async_wait_for(req, NULL);
  149.         async_serialize_end();
  150.         return retval;
  151.     }
  152.    
  153.     async_wait_for(req, &retval);
  154.    
  155.     async_serialize_end();
  156.    
  157.     if (retval != EOK) {
  158.         if (handle != NULL)
  159.             *handle = -1;
  160.         return retval;
  161.     }
  162.    
  163.     if (handle != NULL)
  164.         *handle = (dev_handle_t) IPC_GET_ARG1(answer);
  165.    
  166.     return retval;
  167. }
  168.  
  169. int devmap_device_get_handle(const char *name, dev_handle_t *handle, unsigned int flags)
  170. {
  171.     int phone = devmap_get_phone(DEVMAP_CLIENT, flags);
  172.    
  173.     if (phone < 0)
  174.         return phone;
  175.    
  176.     async_serialize_start();
  177.    
  178.     ipc_call_t answer;
  179.     aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
  180.         &answer);
  181.    
  182.     ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
  183.    
  184.     if (retval != EOK) {
  185.         async_wait_for(req, NULL);
  186.         async_serialize_end();
  187.         return retval;
  188.     }
  189.    
  190.     async_wait_for(req, &retval);
  191.    
  192.     async_serialize_end();
  193.    
  194.     if (retval != EOK) {
  195.         if (handle != NULL)
  196.             *handle = (dev_handle_t) -1;
  197.         return retval;
  198.     }
  199.    
  200.     if (handle != NULL)
  201.         *handle = (dev_handle_t) IPC_GET_ARG1(answer);
  202.    
  203.     return retval;
  204. }
  205.  
  206. int devmap_device_connect(dev_handle_t handle, unsigned int flags)
  207. {
  208.     int phone;
  209.    
  210.     if (flags & IPC_FLAG_BLOCKING) {
  211.         phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP,
  212.             DEVMAP_CONNECT_TO_DEVICE, handle);
  213.     } else {
  214.         phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
  215.             DEVMAP_CONNECT_TO_DEVICE, handle);
  216.     }
  217.    
  218.     return phone;
  219. }
  220.  
  221. int devmap_null_create(void)
  222. {
  223.     int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
  224.    
  225.     if (phone < 0)
  226.         return -1;
  227.    
  228.     ipcarg_t null_id;
  229.     int retval = async_req_0_1(phone, DEVMAP_DEVICE_NULL_CREATE, &null_id);
  230.     if (retval != EOK)
  231.         return -1;
  232.    
  233.     return (int) null_id;
  234. }
  235.  
  236. void devmap_null_destroy(int null_id)
  237. {
  238.     int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
  239.    
  240.     if (phone < 0)
  241.         return;
  242.    
  243.     async_req_1_0(phone, DEVMAP_DEVICE_NULL_DESTROY, (ipcarg_t) null_id);
  244. }
  245.  
  246. ipcarg_t devmap_device_get_count(void)
  247. {
  248.     int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
  249.    
  250.     if (phone < 0)
  251.         return 0;
  252.    
  253.     ipcarg_t count;
  254.     int retval = async_req_0_1(phone, DEVMAP_DEVICE_GET_COUNT, &count);
  255.     if (retval != EOK)
  256.         return 0;
  257.    
  258.     return count;
  259. }
  260.  
  261. ipcarg_t devmap_device_get_devices(ipcarg_t count, dev_desc_t *data)
  262. {
  263.     int phone = devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING);
  264.    
  265.     if (phone < 0)
  266.         return 0;
  267.    
  268.     async_serialize_start();
  269.    
  270.     ipc_call_t answer;
  271.     aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer);
  272.    
  273.     ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));
  274.    
  275.     if (retval != EOK) {
  276.         async_wait_for(req, NULL);
  277.         async_serialize_end();
  278.         return 0;
  279.     }
  280.    
  281.     async_wait_for(req, &retval);
  282.    
  283.     async_serialize_end();
  284.    
  285.     if (retval != EOK)
  286.         return 0;
  287.    
  288.     return IPC_GET_ARG1(answer);
  289. }
  290.