Ignore:
Timestamp:
2010-10-26T13:47:46Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
56cb9bd
Parents:
23cb44b
Message:

Async communication with HCD

Added asynchronous versions of functions for sending/retrieving
data to/from HCD. These work pretty the same as functions for
sending messages in the async framework.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hw/bus/usb/hcd/virtual/connhost.c

    r23cb44b r2185776  
    5252} transaction_details_t;
    5353
     54
    5455/** Callback for outgoing transaction.
    5556 */
     
    193194
    194195
     196typedef struct {
     197        ipc_callid_t caller;
     198        void *buffer;
     199        size_t size;
     200} async_transaction_t;
     201
     202static void async_out_callback(void * buffer, size_t len,
     203    usb_transaction_outcome_t outcome, void * arg)
     204{
     205        async_transaction_t * trans = (async_transaction_t *)arg;
     206       
     207        dprintf(2, "async_out_callback(buffer, %u, %d, %p) -> %x",
     208            len, outcome, arg, trans->caller);
     209       
     210        // FIXME - answer according to outcome
     211        ipc_answer_1(trans->caller, EOK, 0);
     212       
     213        free(trans);
     214        if (buffer) {
     215                free(buffer);
     216        }
     217        dprintf(4, "async_out_callback answered");
     218}
     219
     220static void async_to_device(ipc_callid_t iid, ipc_call_t icall, bool setup_transaction)
     221{
     222        size_t expected_len = IPC_GET_ARG3(icall);
     223        usb_target_t target = {
     224                .address = IPC_GET_ARG1(icall),
     225                .endpoint = IPC_GET_ARG2(icall)
     226        };
     227       
     228        dprintf(1, "async_to_device: dev=%d:%d, size=%d, iid=%x",
     229            target.address, target.endpoint, expected_len, iid);
     230       
     231        size_t len = 0;
     232        void * buffer = NULL;
     233        if (expected_len > 0) {
     234                int rc = async_data_write_accept(&buffer, false,
     235                    1, USB_MAX_PAYLOAD_SIZE,
     236                    0, &len);
     237               
     238                if (rc != EOK) {
     239                        ipc_answer_0(iid, rc);
     240                        return;
     241                }
     242        }
     243       
     244        async_transaction_t * trans = malloc(sizeof(async_transaction_t));
     245        trans->caller = iid;
     246        trans->buffer = NULL;
     247        trans->size = 0;
     248       
     249        hc_add_transaction_to_device(setup_transaction, target,
     250            buffer, len,
     251            async_out_callback, trans);
     252       
     253        dprintf(2, "async transaction to device scheduled (%p)", trans);
     254}
     255
     256static void async_in_callback(void * buffer, size_t len,
     257    usb_transaction_outcome_t outcome, void * arg)
     258{       
     259        async_transaction_t * trans = (async_transaction_t *)arg;
     260       
     261        dprintf(2, "async_in_callback(buffer, %u, %d, %p) -> %x",
     262            len, outcome, arg, trans->caller);
     263       
     264        trans->buffer = buffer;
     265        trans->size = len;
     266       
     267        ipc_callid_t caller = trans->caller;
     268       
     269        if (buffer == NULL) {
     270                free(trans);
     271                trans = NULL;
     272        }
     273       
     274       
     275        // FIXME - answer according to outcome
     276        ipc_answer_1(caller, EOK, (ipcarg_t)trans);
     277        dprintf(4, "async_in_callback answered (%#x)", (ipcarg_t)trans);
     278}
     279
     280static void async_from_device(ipc_callid_t iid, ipc_call_t icall)
     281{
     282        usb_target_t target = {
     283                .address = IPC_GET_ARG1(icall),
     284                .endpoint = IPC_GET_ARG2(icall)
     285        };
     286        size_t len = IPC_GET_ARG3(icall);
     287       
     288        dprintf(1, "async_from_device: dev=%d:%d, size=%d, iid=%x",
     289            target.address, target.endpoint, len, iid);
     290       
     291        void * buffer = NULL;
     292        if (len > 0) {
     293                buffer = malloc(len);
     294        }
     295       
     296        async_transaction_t * trans = malloc(sizeof(async_transaction_t));
     297        trans->caller = iid;
     298        trans->buffer = NULL;
     299        trans->size = 0;
     300       
     301        hc_add_transaction_from_device(target,
     302            buffer, len,
     303            async_in_callback, trans);
     304       
     305        dprintf(2, "async transfer from device scheduled (%p)", trans);
     306}
     307
     308static void async_get_buffer(ipc_callid_t iid, ipc_call_t icall)
     309{
     310        ipcarg_t buffer_hash = IPC_GET_ARG1(icall);
     311        async_transaction_t * trans = (async_transaction_t *)buffer_hash;
     312        if (trans == NULL) {
     313                ipc_answer_0(iid, ENOENT);
     314                return;
     315        }
     316        if (trans->buffer == NULL) {
     317                ipc_answer_0(iid, EINVAL);
     318                free(trans);
     319                return;
     320        }
     321       
     322        ipc_callid_t callid;
     323        size_t accepted_size;
     324        if (!async_data_read_receive(&callid, &accepted_size)) {
     325                ipc_answer_0(iid, EINVAL);
     326                return;
     327        }
     328       
     329        if (accepted_size > trans->size) {
     330                accepted_size = trans->size;
     331        }
     332        async_data_read_finalize(callid, trans->buffer, accepted_size);
     333       
     334        ipc_answer_1(iid, EOK, accepted_size);
     335       
     336        free(trans->buffer);
     337        free(trans);
     338}
     339
    195340
    196341/** Connection handler for communcation with host.
     
    214359               
    215360                callid = async_get_call(&call);
     361               
     362                dprintf(6, "host on %#x calls [%x: %u (%u, %u, %u, %u, %u)]",
     363                    phone_hash,
     364                    callid,
     365                    IPC_GET_METHOD(call),
     366                    IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call),
     367                    IPC_GET_ARG4(call), IPC_GET_ARG5(call));
    216368               
    217369                switch (IPC_GET_METHOD(call)) {
     
    231383                                break;
    232384                       
     385                        /* callback-result methods */
    233386                       
    234387                        case IPC_M_USB_HCD_INTERRUPT_OUT:
     
    259412                                    true, host_phone);
    260413                                break;
    261                                
    262                         case IPC_M_USB_HCD_CONTROL_READ_DATA:
    263                         case IPC_M_USB_HCD_CONTROL_READ_STATUS:
     414                       
     415                        /* async methods */
     416                       
     417                        case IPC_M_USB_HCD_GET_BUFFER_ASYNC:
     418                                async_get_buffer(callid, call);
     419                                break;
     420       
     421                        case IPC_M_USB_HCD_INTERRUPT_OUT_ASYNC:
     422                        case IPC_M_USB_HCD_CONTROL_WRITE_DATA_ASYNC:
     423                        case IPC_M_USB_HCD_CONTROL_READ_STATUS_ASYNC:
     424                                async_to_device(callid, call, false);
     425                                break;
     426                       
     427                        case IPC_M_USB_HCD_CONTROL_WRITE_SETUP_ASYNC:
     428                        case IPC_M_USB_HCD_CONTROL_READ_SETUP_ASYNC:
     429                                async_to_device(callid, call, true);
     430                                break;
     431                       
     432                        case IPC_M_USB_HCD_INTERRUPT_IN_ASYNC:
     433                        case IPC_M_USB_HCD_CONTROL_WRITE_STATUS_ASYNC:
     434                        case IPC_M_USB_HCD_CONTROL_READ_DATA_ASYNC:
     435                                async_from_device(callid, call);
     436                                break;
     437                       
     438                        /* end of known methods */
    264439                       
    265440                        default:
Note: See TracChangeset for help on using the changeset viewer.