Subversion Repositories HelenOS

Rev

Rev 3089 | Blame | Compare with Previous | 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(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
  136.  
  137.     while (phone < 0) {
  138.         usleep(100000);
  139.         phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP,
  140.             DEVMAP_DRIVER, 0);
  141.     }
  142.    
  143.     req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer);
  144.  
  145.     retval = ipc_data_write_start(phone, (char *)name, strlen(name) + 1);
  146.  
  147.     if (retval != EOK) {
  148.         async_wait_for(req, NULL);
  149.         return -1;
  150.     }
  151.  
  152.     async_set_client_connection(driver_client_connection);
  153.  
  154.     ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
  155. /* 
  156.     if (NULL == async_new_connection(callback_phonehash, 0, NULL,
  157.             driver_client_connection)) {
  158.         printf("Failed to create new fibril.\n");  
  159.         async_wait_for(req, NULL);
  160.         return -1;
  161.     }
  162. */
  163.     async_wait_for(req, &retval);
  164.     printf("Driver '%s' registered.\n", name);
  165.  
  166.     return phone;
  167. }
  168.  
  169. static int device_get_handle(int driver_phone, char *name, int *handle)
  170. {
  171.     ipcarg_t retval;
  172.     aid_t req;
  173.     ipc_call_t answer;
  174.  
  175.     req = async_send_2(driver_phone, DEVMAP_DEVICE_GET_HANDLE, 0, 0,
  176.         &answer);
  177.  
  178.     retval = ipc_data_write_start(driver_phone, name, strlen(name) + 1);
  179.  
  180.     if (retval != EOK) {
  181.         printf("Failed to send device name '%s'.\n", name);
  182.         async_wait_for(req, NULL);
  183.         return retval;
  184.     }
  185.  
  186.     async_wait_for(req, &retval);
  187.  
  188.     if (NULL != handle) {
  189.         *handle = -1;
  190.     }
  191.  
  192.     if (EOK == retval) {
  193.        
  194.         if (NULL != handle) {
  195.             *handle = (int) IPC_GET_ARG1(answer);
  196.         }
  197.         printf("Device '%s' has handle %u.\n", name,
  198.             (int) IPC_GET_ARG1(answer));
  199.     } else {
  200.         printf("Failed to get handle for device '%s'.\n", name);
  201.     }
  202.  
  203.     return retval;
  204. }
  205.  
  206. /** Register new device.
  207.  * @param driver_phone
  208.  * @param name Device name.
  209.  * @param handle Output variable. Handle to the created instance of device.
  210.  */
  211. static int device_register(int driver_phone, char *name, int *handle)
  212. {
  213.     ipcarg_t retval;
  214.     aid_t req;
  215.     ipc_call_t answer;
  216.  
  217.     req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer);
  218.  
  219.     retval = ipc_data_write_start(driver_phone, (char *)name,
  220.         strlen(name) + 1);
  221.  
  222.     if (retval != EOK) {
  223.         printf("Failed to send device name '%s'.\n", name);
  224.         async_wait_for(req, NULL);
  225.         return retval;
  226.     }
  227.  
  228.     async_wait_for(req, &retval);
  229.  
  230.     if (NULL != handle) {
  231.         *handle = -1;
  232.     }
  233.  
  234.     if (EOK == retval) {
  235.        
  236.         if (NULL != handle) {
  237.             *handle = (int) IPC_GET_ARG1(answer);
  238.         }
  239.         printf("Device registered with handle %u.\n",
  240.             (int) IPC_GET_ARG1(answer));
  241.     }
  242.  
  243.     return retval;
  244. }
  245.  
  246. /** Test DevMap from the driver's point of view.
  247.  *
  248.  *
  249.  */
  250. char * test_devmap1(bool quiet)
  251. {
  252.     int driver_phone;
  253.     int dev1_handle;
  254.     int dev2_handle;
  255.     int dev3_handle;
  256.     int handle;
  257.  
  258.     /* Register new driver */
  259.     driver_phone = driver_register("TestDriver");
  260.  
  261.     if (driver_phone < 0) {
  262.         return "Error: Cannot register driver.\n"; 
  263.     }
  264.  
  265.     /* Register new device dev1*/
  266.     if (EOK != device_register(driver_phone, TEST_DEVICE1, &dev1_handle)) {
  267.         ipc_hangup(driver_phone);
  268.         return "Error: cannot register device.\n";
  269.     }
  270.  
  271.     /* Get handle for dev2 (Should fail unless device is already
  272.      * registered by someone else)
  273.      */
  274.     if (EOK == device_get_handle(driver_phone, TEST_DEVICE2, &handle)) {
  275.         ipc_hangup(driver_phone);
  276.         return "Error: got handle for dev2 before it was registered.\n";
  277.     }
  278.  
  279.     /* Register new device dev2*/
  280.     if (EOK != device_register(driver_phone, TEST_DEVICE2, &dev2_handle)) {
  281.         ipc_hangup(driver_phone);
  282.         return "Error: cannot register device dev2.\n";
  283.     }
  284.  
  285.     /* Register again device dev1 */
  286.     if (EOK == device_register(driver_phone, TEST_DEVICE1, &dev3_handle)) {
  287.         return "Error: dev1 registered twice.\n";
  288.     }
  289.  
  290.     /* Get handle for dev1*/
  291.     if (EOK != device_get_handle(driver_phone, TEST_DEVICE1, &handle)) {
  292.         ipc_hangup(driver_phone);
  293.         return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
  294.     }
  295.  
  296.     if (handle != dev1_handle) {
  297.         ipc_hangup(driver_phone);
  298.         return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n";
  299.     }
  300.  
  301.     if (EOK != device_client(dev1_handle)) {
  302.         ipc_hangup(driver_phone);
  303.         return "Error: failed client test for 'DEVMAP_DEVICE1'.\n";
  304.     }
  305.  
  306.     /* TODO: */
  307.  
  308.     ipc_hangup(driver_phone);
  309.  
  310.     return NULL;
  311. }
  312.  
  313. char *test_devmap2(bool quiet)
  314. {
  315.     /*TODO: Full automatic test */
  316.     return NULL;
  317. }
  318.  
  319. char *test_devmap3(bool quiet)
  320. {
  321.     /* TODO: allow user to call test functions in random order */
  322.     return NULL;
  323. }
  324.  
  325.