Subversion Repositories HelenOS

Rev

Rev 3150 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2007 Josef Cejka
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <unistd.h>
  31. #include <ipc/ipc.h>
  32. #include <ipc/services.h>
  33. #include <async.h>
  34. #include <errno.h>
  35. #include <ipc/devmap.h>
  36. #include "../tester.h"
  37.  
  38. #include <time.h>
  39.  
  40. #define TEST_DEVICE1 "TestDevice1"
  41. #define TEST_DEVICE2 "TestDevice2"
  42.  
  43. /** Handle requests from clients
  44.  *
  45.  */
  46. static void driver_client_connection(ipc_callid_t iid, ipc_call_t *icall)
  47. {
  48.     ipc_callid_t callid;
  49.     ipc_call_t call;
  50.     int retval;
  51.    
  52.     printf("connected: method=%u arg1=%u, arg2=%u arg3=%u.\n",
  53.         IPC_GET_METHOD(*icall), IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
  54.         IPC_GET_ARG3(*icall));
  55.  
  56.     printf("driver_client_connection.\n");
  57.     ipc_answer_0(iid, EOK);
  58.  
  59.     /* Ignore parameters, the connection is already opened */
  60.     while (1) {
  61.         callid = async_get_call(&call);
  62.         retval = EOK;
  63.         printf("method=%u arg1=%u, arg2=%u arg3=%u.\n",
  64.             IPC_GET_METHOD(call), IPC_GET_ARG1(call),
  65.             IPC_GET_ARG2(call), IPC_GET_ARG3(call));
  66.         switch (IPC_GET_METHOD(call)) {
  67.         case IPC_M_PHONE_HUNGUP:
  68.             /* TODO: Handle hangup */
  69.             return;
  70.         default:
  71.             printf("Unknown device method %u.\n",
  72.                 IPC_GET_METHOD(call));
  73.             retval = ENOENT;
  74.         }
  75.         ipc_answer_0(callid, retval);
  76.     }
  77.     return;
  78. }
  79.  
  80. static int device_client_fibril(void *arg)
  81. {
  82.     int handle;
  83.     int device_phone;
  84.  
  85.     handle = (int)arg;
  86.  
  87.     device_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
  88.         DEVMAP_CONNECT_TO_DEVICE, handle);
  89.  
  90.     if (device_phone < 0) {
  91.         printf("Failed to connect to devmap as client (handle = %u).\n",
  92.             handle);
  93.         return -1;
  94.     }
  95. /* 
  96.  *  device_phone = (int) IPC_GET_ARG5(answer);
  97.  */
  98.     printf("Connected to device.\n");
  99.     ipc_call_sync_1_0(device_phone, 1024, 1025);
  100. /*
  101.  * ipc_hangup(device_phone);
  102.  */
  103.     ipc_hangup(device_phone);
  104.  
  105.     return EOK;
  106. }
  107.  
  108. /** Communication test with device.
  109.  * @param handle handle to tested instance.
  110.  */
  111. static int device_client(int handle)
  112. {
  113. /*  fid_t fid;
  114.     ipc_call_t call;
  115.     ipc_callid_t callid;
  116.  
  117.     fid = fibril_create(device_client_fibril, (void *)handle);
  118.     fibril_add_ready(fid);
  119.  
  120. */
  121.     return EOK;
  122. }
  123.  
  124. /**
  125.  *
  126.  */
  127. static int driver_register(char *name)
  128. {
  129.     ipcarg_t retval;
  130.     aid_t req;
  131.     ipc_call_t answer;
  132.     int phone;
  133.     ipcarg_t callback_phonehash;
  134.  
  135.     phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
  136.     if (phone < 0) {
  137.         printf("Failed to connect to device mapper\n");
  138.         return -1;
  139.     }
  140.    
  141.     req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
  142.  
  143.     retval = ipc_data_write_start(phone, (char *)name, strlen(name) + 1);
  144.  
  145.     if (retval != EOK) {
  146.         async_wait_for(req, NULL);
  147.         return -1;
  148.     }
  149.  
  150.     async_set_client_connection(driver_client_connection);
  151.  
  152.     ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
  153. /* 
  154.     if (NULL == async_new_connection(callback_phonehash, 0, NULL,
  155.             driver_client_connection)) {
  156.         printf("Failed to create new fibril.\n");  
  157.         async_wait_for(req, NULL);
  158.         return -1;
  159.     }
  160. */
  161.     async_wait_for(req, &retval);
  162.     printf("Driver '%s' registered.\n", name);
  163.  
  164.     return phone;
  165. }
  166.  
  167. static int device_get_handle(int driver_phone, char *name, int *handle)
  168. {
  169.     ipcarg_t retval;
  170.     aid_t req;
  171.     ipc_call_t answer;
  172.  
  173.     req = async_send_2(driver_phone, DEVMAP_DEVICE_GET_HANDLE, 0, 0,
  174.         &answer);
  175.  
  176.     retval = ipc_data_write_start(driver_phone, name, strlen(name) + 1);
  177.  
  178.     if (retval != EOK) {
  179.         printf("Failed to send device name '%s'.\n", name);
  180.         async_wait_for(req, NULL);
  181.         return retval;
  182.     }
  183.  
  184.     async_wait_for(req, &retval);
  185.  
  186.     if (NULL != handle) {
  187.         *handle = -1;
  188.     }
  189.  
  190.     if (EOK == retval) {
  191.        
  192.         if (NULL != handle) {
  193.             *handle = (int) IPC_GET_ARG1(answer);
  194.         }
  195.         printf("Device '%s' has handle %u.\n", name,
  196.             (int) IPC_GET_ARG1(answer));
  197.     } else {
  198.         printf("Failed to get handle for device '%s'.\n", name);
  199.     }
  200.  
  201.     return retval;
  202. }
  203.  
  204. /** Register new device.
  205.  * @param driver_phone
  206.  * @param name Device name.
  207.  * @param handle Output variable. Handle to the created instance of device.
  208.  */
  209. static int device_register(int driver_phone, char *name, int *handle)
  210. {
  211.     ipcarg_t retval;
  212.     aid_t req;
  213.     ipc_call_t answer;
  214.  
  215.     req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
  216.  
  217.     retval = ipc_data_write_start(driver_phone, (char *)name,
  218.         strlen(name) + 1);
  219.  
  220.     if (retval != EOK) {
  221.         printf("Failed to send device name '%s'.\n", name);
  222.         async_wait_for(req, NULL);
  223.         return retval;
  224.     }
  225.  
  226.     async_wait_for(req, &retval);
  227.  
  228.     if (NULL != handle) {
  229.         *handle = -1;
  230.     }
  231.  
  232.     if (EOK == retval) {
  233.        
  234.         if (NULL != handle) {
  235.             *handle = (int) IPC_GET_ARG1(answer);
  236.         }
  237.         printf("Device registered with handle %u.\n",
  238.             (int) IPC_GET_ARG1(answer));
  239.     }
  240.  
  241.     return retval;
  242. }
  243.  
  244. /** Test DevMap from the driver's point of view.
  245.  *
  246.  *
  247.  */
  248. char * test_devmap1(bool quiet)
  249. {
  250.     int driver_phone;
  251.     int dev1_handle;
  252.     int dev2_handle;
  253.     int dev3_handle;
  254.     int handle;
  255.  
  256.     /* Register new driver */
  257.     driver_phone = driver_register("TestDriver");
  258.  
  259.     if (driver_phone < 0) {
  260.         return "Error: Cannot register driver.\n"; 
  261.     }
  262.  
  263.     /* Register new device dev1*/
  264.     if (EOK != device_register(driver_phone, TEST_DEVICE1, &dev1_handle)) {
  265.         ipc_hangup(driver_phone);
  266.         return "Error: cannot register device.\n";
  267.     }
  268.  
  269.     /* Get handle for dev2 (Should fail unless device is already
  270.      * registered by someone else)
  271.      */
  272.     if (EOK == device_get_handle(driver_phone, TEST_DEVICE2, &handle)) {
  273.         ipc_hangup(driver_phone);
  274.         return "Error: got handle for dev2 before it was registered.\n";
  275.     }
  276.  
  277.     /* Register new device dev2*/
  278.     if (EOK != device_register(driver_phone, TEST_DEVICE2, &dev2_handle)) {
  279.         ipc_hangup(driver_phone);
  280.         return "Error: cannot register device dev2.\n";
  281.     }
  282.  
  283.     /* Register again device dev1 */
  284.     if (EOK == device_register(driver_phone, TEST_DEVICE1, &dev3_handle)) {
  285.         return "Error: dev1 registered twice.\n";
  286.     }
  287.  
  288.     /* Get handle for dev1*/
  289.     if (EOK != device_get_handle(driver_phone, TEST_DEVICE1, &handle)) {
  290.         ipc_hangup(driver_phone);
  291.         return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
  292.     }
  293.  
  294.     if (handle != dev1_handle) {
  295.         ipc_hangup(driver_phone);
  296.         return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
  297.     }
  298.  
  299.     if (EOK != device_client(dev1_handle)) {
  300.         ipc_hangup(driver_phone);
  301.         return "Error: failed client test for 'DEVMAP_DEVICE1'.\n";
  302.     }
  303.  
  304.     /* TODO: */
  305.  
  306.     ipc_hangup(driver_phone);
  307.  
  308.     return NULL;
  309. }
  310.  
  311. char *test_devmap2(bool quiet)
  312. {
  313.     /*TODO: Full automatic test */
  314.     return NULL;
  315. }
  316.  
  317. char *test_devmap3(bool quiet)
  318. {
  319.     /* TODO: allow user to call test functions in random order */
  320.     return NULL;
  321. }
  322.  
  323.