Subversion Repositories HelenOS

Rev

Rev 2594 | 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 <../../../srv/devmap/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", IPC_GET_METHOD(*icall),
  53.         IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall), IPC_GET_ARG3(*icall));
  54.  
  55.     printf("driver_client_connection.\n");
  56.     ipc_answer_0(iid, EOK);
  57.  
  58.     /* Ignore parameters, the connection is already opened */
  59.     while (1) {
  60.         callid = async_get_call(&call);
  61.         retval = EOK;
  62.         printf("method=%u arg1=%u, arg2=%u arg3=%u.\n", IPC_GET_METHOD(call),
  63.             IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call));
  64.         switch (IPC_GET_METHOD(call)) {
  65.         case IPC_M_PHONE_HUNGUP:
  66.             /* TODO: Handle hangup */
  67.             return;
  68.         default:
  69.             printf("Unknown device method %u.\n", IPC_GET_METHOD(call));
  70.             retval = ENOENT;
  71.         }
  72.         ipc_answer_0(callid, retval);
  73.     }
  74.     return;
  75. }
  76.  
  77. static int device_client_fibril(void *arg)
  78. {
  79.     int handle;
  80.     int device_phone;
  81.  
  82.     handle = (int)arg;
  83.  
  84.     device_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, \
  85.         DEVMAP_CONNECT_TO_DEVICE, handle);
  86.  
  87.     if (device_phone < 0) {
  88.         printf("Failed to connect to devmap as client (handle = %u).\n",
  89.             handle);
  90.         return -1;
  91.     }
  92. /* 
  93.  *  device_phone = (int) IPC_GET_ARG3(answer);
  94.  */
  95.     printf("Connected to device.\n");
  96.     ipc_call_sync_1_0(device_phone, 1024, 1025);
  97. /*
  98.  * ipc_hangup(device_phone);
  99.  */
  100.     ipc_hangup(device_phone);
  101.  
  102.     return EOK;
  103. }
  104.  
  105. /** Communication test with device.
  106.  * @param handle handle to tested instance.
  107.  */
  108. static int device_client(int handle)
  109. {
  110. /*  fid_t fid;
  111.     ipc_call_t call;
  112.     ipc_callid_t callid;
  113.  
  114.     fid = fibril_create(device_client_fibril, (void *)handle);
  115.     fibril_add_ready(fid);
  116.  
  117. */
  118.     return EOK;
  119. }
  120.  
  121. /**
  122.  *
  123.  */
  124. static int driver_register(char *name)
  125. {
  126.     ipcarg_t retval;
  127.     aid_t req;
  128.     ipc_call_t answer;
  129.     int phone;
  130.     ipcarg_t callback_phonehash;
  131.  
  132.     phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
  133.         DEVMAP_DRIVER, 0);
  134.  
  135.     while (phone < 0) {
  136.         usleep(100000);
  137.         phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
  138.             DEVMAP_DRIVER, 0);
  139.     }
  140.    
  141.     req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
  142.  
  143.     retval = ipc_data_send(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, &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, &answer);
  174.  
  175.     retval = ipc_data_send(driver_phone, name, strlen(name) + 1);
  176.  
  177.     if (retval != EOK) {
  178.         printf("Failed to send device name '%s'.\n", name);
  179.         async_wait_for(req, NULL);
  180.         return retval;
  181.     }
  182.  
  183.     async_wait_for(req, &retval);
  184.  
  185.     if (NULL != handle) {
  186.         *handle = -1;
  187.     }
  188.  
  189.     if (EOK == retval) {
  190.        
  191.         if (NULL != handle) {
  192.             *handle = (int) IPC_GET_ARG1(answer);
  193.         }
  194.         printf("Device '%s' has handle %u.\n", name, (int) IPC_GET_ARG1(answer));
  195.     } else {
  196.         printf("Failed to get handle for device '%s'.\n", name);
  197.     }
  198.  
  199.     return retval;
  200. }
  201.  
  202. /** Register new device.
  203.  * @param driver_phone
  204.  * @param name Device name.
  205.  * @param handle Output variable. Handle to the created instance of device.
  206.  */
  207. static int device_register(int driver_phone, char *name, int *handle)
  208. {
  209.     ipcarg_t retval;
  210.     aid_t req;
  211.     ipc_call_t answer;
  212.  
  213.     req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
  214.  
  215.     retval = ipc_data_send(driver_phone, (char *)name, strlen(name) + 1);
  216.  
  217.     if (retval != EOK) {
  218.         printf("Failed to send device name '%s'.\n", name);
  219.         async_wait_for(req, NULL);
  220.         return retval;
  221.     }
  222.  
  223.     async_wait_for(req, &retval);
  224.  
  225.     if (NULL != handle) {
  226.         *handle = -1;
  227.     }
  228.  
  229.     if (EOK == retval) {
  230.        
  231.         if (NULL != handle) {
  232.             *handle = (int) IPC_GET_ARG1(answer);
  233.         }
  234.         printf("Device registered with handle %u.\n", (int) IPC_GET_ARG1(answer));
  235.     }
  236.  
  237.     return retval;
  238. }
  239.  
  240. /** Test DevMap from the driver's point of view.
  241.  *
  242.  *
  243.  */
  244. char * test_devmap1(bool quiet)
  245. {
  246.     int driver_phone;
  247.     int dev1_handle;
  248.     int dev2_handle;
  249.     int dev3_handle;
  250.     int handle;
  251.  
  252.     /* Register new driver */
  253.     driver_phone = driver_register("TestDriver");
  254.  
  255.     if (driver_phone < 0) {
  256.         return "Error: Cannot register driver.\n"; 
  257.     }
  258.  
  259.     /* Register new device dev1*/
  260.     if (EOK != device_register(driver_phone, TEST_DEVICE1, &dev1_handle)) {
  261.         ipc_hangup(driver_phone);
  262.         return "Error: cannot register device.\n";
  263.     }
  264.  
  265.     /* Get handle for dev2 (Should fail unless device is already
  266.      * registered by someone else)
  267.      */
  268.     if (EOK == device_get_handle(driver_phone, TEST_DEVICE2, &handle)) {
  269.         ipc_hangup(driver_phone);
  270.         return "Error: got handle for dev2 before it was registered.\n";
  271.     }
  272.  
  273.     /* Register new device dev2*/
  274.     if (EOK != device_register(driver_phone, TEST_DEVICE2, &dev2_handle)) {
  275.         ipc_hangup(driver_phone);
  276.         return "Error: cannot register device dev2.\n";
  277.     }
  278.  
  279.     /* Register again device dev1 */
  280.     if (EOK == device_register(driver_phone, TEST_DEVICE1, &dev3_handle)) {
  281.         return "Error: dev1 registered twice.\n";
  282.     }
  283.  
  284.     /* Get handle for dev1*/
  285.     if (EOK != device_get_handle(driver_phone, TEST_DEVICE1, &handle)) {
  286.         ipc_hangup(driver_phone);
  287.         return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
  288.     }
  289.  
  290.     if (handle != dev1_handle) {
  291.         ipc_hangup(driver_phone);
  292.         return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
  293.     }
  294.  
  295.     if (EOK != device_client(dev1_handle)) {
  296.         ipc_hangup(driver_phone);
  297.         return "Error: failed client test for 'DEVMAP_DEVICE1'.\n";
  298.     }
  299.  
  300.     /* TODO: */
  301.  
  302.     ipc_hangup(driver_phone);
  303.  
  304.     return NULL;
  305. }
  306.  
  307. char *test_devmap2(bool quiet)
  308. {
  309.     /*TODO: Full automatic test */
  310.     return NULL;
  311. }
  312.  
  313. char *test_devmap3(bool quiet)
  314. {
  315.     /* TODO: allow user to call test functions in random order */
  316.     return NULL;
  317. }
  318.  
  319.