Changeset 4b4c797 in mainline for uspace/drv/vhc/connhost.c
- Timestamp:
- 2010-11-20T14:07:05Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1b22bd4
- Parents:
- 0e126be7
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/vhc/connhost.c
r0e126be7 r4b4c797 35 35 #include <assert.h> 36 36 #include <errno.h> 37 #include <usb/ hcd.h>37 #include <usb/usb.h> 38 38 39 39 #include "vhcd.h" 40 40 #include "conn.h" 41 41 #include "hc.h" 42 43 typedef struct {44 ipc_callid_t caller;45 void *buffer;46 size_t size;47 } async_transaction_t;48 49 static void async_out_callback(void * buffer, size_t len,50 usb_transaction_outcome_t outcome, void * arg)51 {52 async_transaction_t * trans = (async_transaction_t *)arg;53 54 dprintf(2, "async_out_callback(buffer, %u, %d, %p) -> %x",55 len, outcome, arg, trans->caller);56 57 // FIXME - answer according to outcome58 ipc_answer_1(trans->caller, EOK, 0);59 60 free(trans);61 if (buffer) {62 free(buffer);63 }64 dprintf(4, "async_out_callback answered");65 }66 67 static void async_to_device(ipc_callid_t iid, ipc_call_t icall, bool setup_transaction)68 {69 size_t expected_len = IPC_GET_ARG3(icall);70 usb_target_t target = {71 .address = IPC_GET_ARG1(icall),72 .endpoint = IPC_GET_ARG2(icall)73 };74 75 dprintf(1, "async_to_device: dev=%d:%d, size=%d, iid=%x",76 target.address, target.endpoint, expected_len, iid);77 78 size_t len = 0;79 void * buffer = NULL;80 if (expected_len > 0) {81 int rc = async_data_write_accept(&buffer, false,82 1, USB_MAX_PAYLOAD_SIZE,83 0, &len);84 85 if (rc != EOK) {86 ipc_answer_0(iid, rc);87 return;88 }89 }90 91 async_transaction_t * trans = malloc(sizeof(async_transaction_t));92 trans->caller = iid;93 trans->buffer = NULL;94 trans->size = 0;95 96 hc_add_transaction_to_device(setup_transaction, target,97 buffer, len,98 async_out_callback, trans);99 100 dprintf(2, "async transaction to device scheduled (%p)", trans);101 }102 103 static void async_in_callback(void * buffer, size_t len,104 usb_transaction_outcome_t outcome, void * arg)105 {106 async_transaction_t * trans = (async_transaction_t *)arg;107 108 dprintf(2, "async_in_callback(buffer, %u, %d, %p) -> %x",109 len, outcome, arg, trans->caller);110 111 trans->buffer = buffer;112 trans->size = len;113 114 ipc_callid_t caller = trans->caller;115 116 if (buffer == NULL) {117 free(trans);118 trans = NULL;119 }120 121 122 // FIXME - answer according to outcome123 ipc_answer_1(caller, EOK, (ipcarg_t)trans);124 dprintf(4, "async_in_callback answered (%#x)", (ipcarg_t)trans);125 }126 127 static void async_from_device(ipc_callid_t iid, ipc_call_t icall)128 {129 usb_target_t target = {130 .address = IPC_GET_ARG1(icall),131 .endpoint = IPC_GET_ARG2(icall)132 };133 size_t len = IPC_GET_ARG3(icall);134 135 dprintf(1, "async_from_device: dev=%d:%d, size=%d, iid=%x",136 target.address, target.endpoint, len, iid);137 138 void * buffer = NULL;139 if (len > 0) {140 buffer = malloc(len);141 }142 143 async_transaction_t * trans = malloc(sizeof(async_transaction_t));144 trans->caller = iid;145 trans->buffer = NULL;146 trans->size = 0;147 148 hc_add_transaction_from_device(target,149 buffer, len,150 async_in_callback, trans);151 152 dprintf(2, "async transfer from device scheduled (%p)", trans);153 }154 155 static void async_get_buffer(ipc_callid_t iid, ipc_call_t icall)156 {157 ipcarg_t buffer_hash = IPC_GET_ARG1(icall);158 async_transaction_t * trans = (async_transaction_t *)buffer_hash;159 if (trans == NULL) {160 ipc_answer_0(iid, ENOENT);161 return;162 }163 if (trans->buffer == NULL) {164 ipc_answer_0(iid, EINVAL);165 free(trans);166 return;167 }168 169 ipc_callid_t callid;170 size_t accepted_size;171 if (!async_data_read_receive(&callid, &accepted_size)) {172 ipc_answer_0(iid, EINVAL);173 return;174 }175 176 if (accepted_size > trans->size) {177 accepted_size = trans->size;178 }179 async_data_read_finalize(callid, trans->buffer, accepted_size);180 181 ipc_answer_1(iid, EOK, accepted_size);182 183 free(trans->buffer);184 free(trans);185 }186 187 188 /** Connection handler for communcation with host.189 * By host is typically meant top-level USB driver.190 *191 * This function also takes care of proper phone hung-up.192 *193 * @param phone_hash Incoming phone hash.194 */195 void connection_handler_host(ipcarg_t phone_hash)196 {197 dprintf(0, "host connected through phone %#x", phone_hash);198 199 200 while (true) {201 ipc_callid_t callid;202 ipc_call_t call;203 204 callid = async_get_call(&call);205 206 dprintf(6, "host on %#x calls [%x: %u (%u, %u, %u, %u, %u)]",207 phone_hash,208 callid,209 IPC_GET_METHOD(call),210 IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call),211 IPC_GET_ARG4(call), IPC_GET_ARG5(call));212 213 switch (IPC_GET_METHOD(call)) {214 215 /* standard IPC methods */216 217 case IPC_M_PHONE_HUNGUP:218 ipc_answer_0(callid, EOK);219 dprintf(0, "phone%#x: host hung-up",220 phone_hash);221 return;222 223 case IPC_M_CONNECT_TO_ME:224 ipc_answer_0(callid, ELIMIT);225 break;226 227 228 /* USB methods */229 230 case IPC_M_USB_HCD_TRANSACTION_SIZE:231 ipc_answer_1(callid, EOK, USB_MAX_PAYLOAD_SIZE);232 break;233 234 case IPC_M_USB_HCD_GET_BUFFER_ASYNC:235 async_get_buffer(callid, call);236 break;237 238 case IPC_M_USB_HCD_INTERRUPT_OUT_ASYNC:239 case IPC_M_USB_HCD_CONTROL_WRITE_DATA_ASYNC:240 case IPC_M_USB_HCD_CONTROL_READ_STATUS_ASYNC:241 async_to_device(callid, call, false);242 break;243 244 case IPC_M_USB_HCD_CONTROL_WRITE_SETUP_ASYNC:245 case IPC_M_USB_HCD_CONTROL_READ_SETUP_ASYNC:246 async_to_device(callid, call, true);247 break;248 249 case IPC_M_USB_HCD_INTERRUPT_IN_ASYNC:250 case IPC_M_USB_HCD_CONTROL_WRITE_STATUS_ASYNC:251 case IPC_M_USB_HCD_CONTROL_READ_DATA_ASYNC:252 async_from_device(callid, call);253 break;254 255 256 /* end of known methods */257 258 default:259 dprintf_inval_call(2, call, phone_hash);260 ipc_answer_0(callid, EINVAL);261 break;262 }263 }264 }265 42 266 43 static int enqueue_transfer_out(usb_hc_device_t *hc,
Note:
See TracChangeset
for help on using the changeset viewer.