00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
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