remote_char_dev.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010 Lenka Trochtova
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00035 #include <async.h>
00036 #include <errno.h>
00037 
00038 #include "ops/char_dev.h"
00039 #include "ddf/driver.h"
00040 
00041 #define MAX_CHAR_RW_COUNT 256
00042 
00043 static void remote_char_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
00044 static void remote_char_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
00045 
00047 static remote_iface_func_ptr_t remote_char_dev_iface_ops[] = {
00048         &remote_char_read,
00049         &remote_char_write
00050 };
00051 
00057 remote_iface_t remote_char_dev_iface = {
00058         .method_count = sizeof(remote_char_dev_iface_ops) /
00059             sizeof(remote_iface_func_ptr_t),
00060         .methods = remote_char_dev_iface_ops
00061 };
00062 
00072 static void
00073 remote_char_read(ddf_fun_t *fun, void *ops, ipc_callid_t callid,
00074     ipc_call_t *call)
00075 {
00076         char_dev_ops_t *char_dev_ops = (char_dev_ops_t *) ops;
00077         ipc_callid_t cid;
00078         
00079         size_t len;
00080         if (!async_data_read_receive(&cid, &len)) {
00081                 /* TODO handle protocol error. */
00082                 async_answer_0(callid, EINVAL);
00083                 return;
00084         }
00085         
00086         if (!char_dev_ops->read) {
00087                 async_data_read_finalize(cid, NULL, 0);
00088                 async_answer_0(callid, ENOTSUP);
00089                 return;
00090         }
00091         
00092         if (len > MAX_CHAR_RW_COUNT)
00093                 len = MAX_CHAR_RW_COUNT;
00094         
00095         char buf[MAX_CHAR_RW_COUNT];
00096         int ret = (*char_dev_ops->read)(fun, buf, len);
00097         
00098         if (ret < 0) {
00099                 /* Some error occured. */
00100                 async_data_read_finalize(cid, buf, 0);
00101                 async_answer_0(callid, ret);
00102                 return;
00103         }
00104         
00105         /* The operation was successful, return the number of data read. */
00106         async_data_read_finalize(cid, buf, ret);
00107         async_answer_1(callid, EOK, ret);
00108 }
00109 
00119 static void
00120 remote_char_write(ddf_fun_t *fun, void *ops, ipc_callid_t callid,
00121     ipc_call_t *call)
00122 {
00123         char_dev_ops_t *char_dev_ops = (char_dev_ops_t *) ops;
00124         ipc_callid_t cid;
00125         size_t len;
00126         
00127         if (!async_data_write_receive(&cid, &len)) {
00128                 /* TODO handle protocol error. */
00129                 async_answer_0(callid, EINVAL);
00130                 return;
00131         }
00132         
00133         if (!char_dev_ops->write) {
00134                 async_data_write_finalize(cid, NULL, 0);
00135                 async_answer_0(callid, ENOTSUP);
00136                 return;
00137         }
00138         
00139         if (len > MAX_CHAR_RW_COUNT)
00140                 len = MAX_CHAR_RW_COUNT;
00141         
00142         char buf[MAX_CHAR_RW_COUNT];
00143         
00144         async_data_write_finalize(cid, buf, len);
00145         
00146         int ret = (*char_dev_ops->write)(fun, buf, len);
00147         if (ret < 0) {
00148                 /* Some error occured. */
00149                 async_answer_0(callid, ret);
00150         } else {
00151                 /*
00152                  * The operation was successful, return the number of data
00153                  * written.
00154                  */
00155                 async_answer_1(callid, EOK, ret);
00156         }
00157 }
00158 

Generated on Thu Jun 2 07:45:47 2011 for HelenOS/USB by  doxygen 1.4.7