ipc_hc.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011 Vojtech Horky
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 <errno.h>
00036 #include <str.h>
00037 #include <stdio.h>
00038 #include <assert.h>
00039 #include <async.h>
00040 #include <devman.h>
00041 #include <usbvirt/device.h>
00042 #include <usbvirt/ipc.h>
00043 #include <usb/debug.h>
00044 
00056 int usbvirt_ipc_send_control_read(int phone,
00057     void *setup_buffer, size_t setup_buffer_size,
00058     void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
00059 {
00060         if (phone < 0) {
00061                 return EINVAL;
00062         }
00063         if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
00064                 return EINVAL;
00065         }
00066         if ((data_buffer == NULL) || (data_buffer_size == 0)) {
00067                 return EINVAL;
00068         }
00069 
00070         aid_t opening_request = async_send_0(phone,
00071             IPC_M_USBVIRT_CONTROL_READ, NULL);
00072         if (opening_request == 0) {
00073                 return ENOMEM;
00074         }
00075 
00076         int rc = async_data_write_start(phone,
00077             setup_buffer, setup_buffer_size);
00078         if (rc != EOK) {
00079                 async_wait_for(opening_request, NULL);
00080                 return rc;
00081         }
00082 
00083         ipc_call_t data_request_call;
00084         aid_t data_request = async_data_read(phone,
00085             data_buffer, data_buffer_size,
00086             &data_request_call);
00087 
00088         if (data_request == 0) {
00089                 async_wait_for(opening_request, NULL);
00090                 return ENOMEM;
00091         }
00092 
00093         sysarg_t data_request_rc;
00094         sysarg_t opening_request_rc;
00095         async_wait_for(data_request, &data_request_rc);
00096         async_wait_for(opening_request, &opening_request_rc);
00097 
00098         if (data_request_rc != EOK) {
00099                 /* Prefer the return code of the opening request. */
00100                 if (opening_request_rc != EOK) {
00101                         return (int) opening_request_rc;
00102                 } else {
00103                         return (int) data_request_rc;
00104                 }
00105         }
00106         if (opening_request_rc != EOK) {
00107                 return (int) opening_request_rc;
00108         }
00109 
00110         if (data_transfered_size != NULL) {
00111                 *data_transfered_size = IPC_GET_ARG2(data_request_call);
00112         }
00113 
00114         return EOK;
00115 }
00116 
00127 int usbvirt_ipc_send_control_write(int phone,
00128     void *setup_buffer, size_t setup_buffer_size,
00129     void *data_buffer, size_t data_buffer_size)
00130 {
00131         if (phone < 0) {
00132                 return EINVAL;
00133         }
00134         if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
00135                 return EINVAL;
00136         }
00137         if ((data_buffer_size > 0) && (data_buffer == NULL)) {
00138                 return EINVAL;
00139         }
00140 
00141         aid_t opening_request = async_send_1(phone,
00142             IPC_M_USBVIRT_CONTROL_WRITE, data_buffer_size,  NULL);
00143         if (opening_request == 0) {
00144                 return ENOMEM;
00145         }
00146 
00147         int rc = async_data_write_start(phone,
00148             setup_buffer, setup_buffer_size);
00149         if (rc != EOK) {
00150                 async_wait_for(opening_request, NULL);
00151                 return rc;
00152         }
00153 
00154         if (data_buffer_size > 0) {
00155                 rc = async_data_write_start(phone,
00156                     data_buffer, data_buffer_size);
00157 
00158                 if (rc != EOK) {
00159                         async_wait_for(opening_request, NULL);
00160                         return rc;
00161                 }
00162         }
00163 
00164         sysarg_t opening_request_rc;
00165         async_wait_for(opening_request, &opening_request_rc);
00166 
00167         return (int) opening_request_rc;
00168 }
00169 
00180 int usbvirt_ipc_send_data_in(int phone, usb_endpoint_t ep,
00181     usb_transfer_type_t tr_type, void *data, size_t data_size, size_t *act_size)
00182 {
00183         if (phone < 0) {
00184                 return EINVAL;
00185         }
00186         usbvirt_hc_to_device_method_t method;
00187         switch (tr_type) {
00188         case USB_TRANSFER_INTERRUPT:
00189                 method = IPC_M_USBVIRT_INTERRUPT_IN;
00190                 break;
00191         case USB_TRANSFER_BULK:
00192                 method = IPC_M_USBVIRT_BULK_IN;
00193                 break;
00194         default:
00195                 return EINVAL;
00196         }
00197         if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX)) {
00198                 return EINVAL;
00199         }
00200         if ((data == NULL) || (data_size == 0)) {
00201                 return EINVAL;
00202         }
00203 
00204 
00205         aid_t opening_request = async_send_2(phone, method, ep, tr_type, NULL);
00206         if (opening_request == 0) {
00207                 return ENOMEM;
00208         }
00209 
00210 
00211         ipc_call_t data_request_call;
00212         aid_t data_request = async_data_read(phone,
00213             data, data_size,  &data_request_call);
00214 
00215         if (data_request == 0) {
00216                 async_wait_for(opening_request, NULL);
00217                 return ENOMEM;
00218         }
00219 
00220         sysarg_t data_request_rc;
00221         sysarg_t opening_request_rc;
00222         async_wait_for(data_request, &data_request_rc);
00223         async_wait_for(opening_request, &opening_request_rc);
00224 
00225         if (data_request_rc != EOK) {
00226                 /* Prefer the return code of the opening request. */
00227                 if (opening_request_rc != EOK) {
00228                         return (int) opening_request_rc;
00229                 } else {
00230                         return (int) data_request_rc;
00231                 }
00232         }
00233         if (opening_request_rc != EOK) {
00234                 return (int) opening_request_rc;
00235         }
00236 
00237         if (act_size != NULL) {
00238                 *act_size = IPC_GET_ARG2(data_request_call);
00239         }
00240 
00241         return EOK;
00242 }
00243 
00253 int usbvirt_ipc_send_data_out(int phone, usb_endpoint_t ep,
00254     usb_transfer_type_t tr_type, void *data, size_t data_size)
00255 {
00256         if (phone < 0) {
00257                 return EINVAL;
00258         }
00259         usbvirt_hc_to_device_method_t method;
00260         switch (tr_type) {
00261         case USB_TRANSFER_INTERRUPT:
00262                 method = IPC_M_USBVIRT_INTERRUPT_OUT;
00263                 break;
00264         case USB_TRANSFER_BULK:
00265                 method = IPC_M_USBVIRT_BULK_OUT;
00266                 break;
00267         default:
00268                 return EINVAL;
00269         }
00270         if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX)) {
00271                 return EINVAL;
00272         }
00273         if ((data == NULL) || (data_size == 0)) {
00274                 return EINVAL;
00275         }
00276 
00277         aid_t opening_request = async_send_1(phone, method, ep, NULL);
00278         if (opening_request == 0) {
00279                 return ENOMEM;
00280         }
00281 
00282         int rc = async_data_write_start(phone,
00283             data, data_size);
00284         if (rc != EOK) {
00285                 async_wait_for(opening_request, NULL);
00286                 return rc;
00287         }
00288 
00289         sysarg_t opening_request_rc;
00290         async_wait_for(opening_request, &opening_request_rc);
00291 
00292         return (int) opening_request_rc;
00293 }
00294 
00295 

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