Changes in / [4e38d69:03197ffc] in mainline


Ignore:
Location:
uspace
Files:
2 added
3 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/async.c

    r4e38d69 r03197ffc  
    15671567}
    15681568
    1569 /** Start IPC_M_DATA_READ using the async framework.
    1570  *
    1571  * @param phoneid Phone that will be used to contact the receiving side.
    1572  * @param dst Address of the beginning of the destination buffer.
    1573  * @param size Size of the destination buffer (in bytes).
    1574  * @param dataptr Storage of call data (arg 2 holds actual data size).
    1575  * @return Hash of the sent message or 0 on error.
    1576  */
    1577 aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)
    1578 {
    1579         return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
    1580             (sysarg_t) size, dataptr);
    1581 }
    1582 
    15831569/** Wrapper for IPC_M_DATA_READ calls using the async framework.
    15841570 *
  • uspace/lib/c/include/async.h

    r4e38d69 r03197ffc  
    340340            (arg4), (answer))
    341341
    342 extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);
    343342extern int async_data_read_start(int, void *, size_t);
    344343extern bool async_data_read_receive(ipc_callid_t *, size_t *);
  • uspace/lib/drv/generic/remote_usbhc.c

    r4e38d69 r03197ffc  
    4242
    4343static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     44static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4445static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4546static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    6364        remote_usbhc_get_address,
    6465
     66        remote_usbhc_get_buffer,
     67
    6568        remote_usbhc_reserve_default_address,
    6669        remote_usbhc_release_default_address,
     
    9598typedef struct {
    9699        ipc_callid_t caller;
    97         ipc_callid_t data_caller;
    98100        void *buffer;
    99101        void *setup_packet;
     
    125127
    126128        trans->caller = caller;
    127         trans->data_caller = 0;
    128129        trans->buffer = NULL;
    129130        trans->setup_packet = NULL;
     
    154155}
    155156
     157void remote_usbhc_get_buffer(device_t *device, void *iface,
     158    ipc_callid_t callid, ipc_call_t *call)
     159{
     160        sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call);
     161        async_transaction_t * trans = (async_transaction_t *)buffer_hash;
     162        if (trans == NULL) {
     163                async_answer_0(callid, ENOENT);
     164                return;
     165        }
     166        if (trans->buffer == NULL) {
     167                async_answer_0(callid, EINVAL);
     168                async_transaction_destroy(trans);
     169                return;
     170        }
     171
     172        ipc_callid_t cid;
     173        size_t accepted_size;
     174        if (!async_data_read_receive(&cid, &accepted_size)) {
     175                async_answer_0(callid, EINVAL);
     176                async_transaction_destroy(trans);
     177                return;
     178        }
     179
     180        if (accepted_size > trans->size) {
     181                accepted_size = trans->size;
     182        }
     183        async_data_read_finalize(cid, trans->buffer, accepted_size);
     184
     185        async_answer_1(callid, EOK, accepted_size);
     186
     187        async_transaction_destroy(trans);
     188}
     189
    156190void remote_usbhc_reserve_default_address(device_t *device, void *iface,
    157191    ipc_callid_t callid, ipc_call_t *call)
     
    261295
    262296        trans->size = actual_size;
    263 
    264         if (trans->data_caller) {
    265                 async_data_read_finalize(trans->data_caller,
    266                     trans->buffer, actual_size);
    267         }
    268 
    269         async_answer_0(trans->caller, USB_OUTCOME_OK);
    270 
    271         async_transaction_destroy(trans);
     297        async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans);
    272298}
    273299
     
    350376        };
    351377
    352         ipc_callid_t data_callid;
    353         if (!async_data_read_receive(&data_callid, &len)) {
    354                 async_answer_0(callid, EPARTY);
    355                 return;
    356         }
    357 
    358378        async_transaction_t *trans = async_transaction_create(callid);
    359379        if (trans == NULL) {
     
    361381                return;
    362382        }
    363         trans->data_caller = data_callid;
    364383        trans->buffer = malloc(len);
    365384        trans->size = len;
     
    611630        }
    612631
    613         ipc_callid_t data_callid;
    614         if (!async_data_read_receive(&data_callid, &data_len)) {
    615                 async_answer_0(callid, EPARTY);
    616                 free(setup_packet);
    617                 return;
    618         }
    619 
    620632        async_transaction_t *trans = async_transaction_create(callid);
    621633        if (trans == NULL) {
     
    624636                return;
    625637        }
    626         trans->data_caller = data_callid;
    627638        trans->setup_packet = setup_packet;
    628639        trans->size = data_len;
  • uspace/lib/drv/include/usbhc_iface.h

    r4e38d69 r03197ffc  
    6666 *   - argument #2 is target endpoint
    6767 *   - argument #3 is buffer size
    68  * - this call is immediately followed by IPC data read (async version)
    6968 * - the call is not answered until the device returns some data (or until
    7069 *   error occurs)
     70 * - if the call is answered with EOK, first argument of the answer is buffer
     71 *   hash that could be used to retrieve the actual data
    7172 *
    7273 * Some special methods (NO-DATA transactions) do not send any data. These
    7374 * might behave as both OUT or IN transactions because communication parts
    7475 * where actual buffers are exchanged are omitted.
    75  **
     76 *
     77 * The mentioned data retrieval can be done any time after receiving EOK
     78 * answer to IN method.
     79 * This retrieval is done using the IPC_M_USBHC_GET_BUFFER where
     80 * the first argument is buffer hash from call answer.
     81 * This call must be immediately followed by data read-in and after the
     82 * data are transferred, the initial call (IPC_M_USBHC_GET_BUFFER)
     83 * is answered. Each buffer can be retrieved only once.
     84 *
    7685 * For all these methods, wrap functions exists. Important rule: functions
    7786 * for IN transactions have (as parameters) buffers where retrieved data
     
    95104        IPC_M_USBHC_GET_ADDRESS,
    96105
     106        /** Asks for data buffer.
     107         * See explanation at usb_iface_funcs_t.
     108         * This function does not have counter part in functional interface
     109         * as it is handled by the remote part itself.
     110         */
     111        IPC_M_USBHC_GET_BUFFER,
     112
    97113
    98114        /** Reserve usage of default address.
  • uspace/lib/usb/src/usbdrv.c

    r4e38d69 r03197ffc  
    4949        /** Storage for actual number of bytes transferred. */
    5050        size_t *size_transferred;
    51         /** Initial call reply data. */
     51        /** Initial call replay data. */
    5252        ipc_call_t reply;
    5353        /** Initial call identifier. */
    5454        aid_t request;
    55         /** Reply data for data read call. */
    56         ipc_call_t read_reply;
    57         /** Data read call identifier. */
    58         aid_t read_request;
    5955} transfer_info_t;
    6056
     
    144140
    145141        if (rc != EOK) {
     142                printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc));
    146143                return rc;
    147144        }
     
    253250        }
    254251
    255         transfer->read_request = 0;
    256252        transfer->size_transferred = NULL;
    257253        transfer->buffer = NULL;
     
    319315        }
    320316
    321         transfer->read_request = 0;
    322317        transfer->size_transferred = actual_size;
    323318        transfer->buffer = buffer;
     
    332327            &transfer->reply);
    333328
    334         if (buffer != NULL) {
    335                 transfer->read_request = async_data_read(phone, buffer, size,
    336                     &transfer->read_reply);
    337         }
    338 
    339329        *handle = (usb_handle_t) transfer;
    340330
     
    342332}
    343333
     334/** Read buffer from HCD.
     335 *
     336 * @param phone Opened phone to HCD.
     337 * @param hash Buffer hash (obtained after completing IN transaction).
     338 * @param buffer Buffer where to store data data.
     339 * @param size Buffer size.
     340 * @param actual_size Storage where actual number of bytes transferred will
     341 *      be stored.
     342 * @return Error status.
     343 */
     344static int read_buffer_in(int phone, sysarg_t hash,
     345    void *buffer, size_t size, size_t *actual_size)
     346{
     347        ipc_call_t answer_data;
     348        sysarg_t answer_rc;
     349        aid_t req;
     350        int rc;
     351
     352        req = async_send_2(phone,
     353            DEV_IFACE_ID(USBHC_DEV_IFACE),
     354            IPC_M_USBHC_GET_BUFFER,
     355            hash,
     356            &answer_data);
     357
     358        rc = async_data_read_start(phone, buffer, size);
     359        if (rc != EOK) {
     360                async_wait_for(req, NULL);
     361                return EINVAL;
     362        }
     363
     364        async_wait_for(req, &answer_rc);
     365        rc = (int)answer_rc;
     366
     367        if (rc != EOK) {
     368                return rc;
     369        }
     370
     371        *actual_size = IPC_GET_ARG1(answer_data);
     372
     373        return EOK;
     374}
    344375
    345376/** Blocks caller until given USB transaction is finished.
     
    364395
    365396        sysarg_t answer_rc;
     397        async_wait_for(transfer->request, &answer_rc);
     398
     399        if (answer_rc != EOK) {
     400                rc = (int) answer_rc;
     401                goto leave;
     402        }
    366403
    367404        /*
     
    369406         */
    370407        if ((transfer->buffer != NULL) && (transfer->size > 0)) {
    371                 async_wait_for(transfer->read_request, &answer_rc);
    372 
    373                 if (answer_rc != EOK) {
    374                         rc = (int) answer_rc;
     408                /*
     409                 * The buffer hash identifies the data on the server
     410                 * side.
     411                 * We will use it when actually reading-in the data.
     412                 */
     413                sysarg_t buffer_hash = IPC_GET_ARG1(transfer->reply);
     414                if (buffer_hash == 0) {
     415                        rc = ENOENT;
    375416                        goto leave;
    376417                }
    377418
    378                 if (transfer->size_transferred != NULL) {
    379                         *(transfer->size_transferred)
    380                             = IPC_GET_ARG2(transfer->read_reply);
     419                size_t actual_size;
     420                rc = read_buffer_in(transfer->phone, buffer_hash,
     421                    transfer->buffer, transfer->size, &actual_size);
     422
     423                if (rc != EOK) {
     424                        goto leave;
    381425                }
    382         }
    383 
    384         async_wait_for(transfer->request, &answer_rc);
    385 
    386         if (answer_rc != EOK) {
    387                 rc = (int) answer_rc;
    388                 goto leave;
     426
     427                if (transfer->size_transferred) {
     428                        *(transfer->size_transferred) = actual_size;
     429                }
    389430        }
    390431
     
    474515        }
    475516
    476         transfer->read_request = 0;
    477517        transfer->size_transferred = NULL;
    478518        transfer->buffer = NULL;
     
    580620        }
    581621
    582         transfer->read_request = async_data_read(phone, buffer, buffer_size,
    583             &transfer->read_reply);
    584 
    585622        *handle = (usb_handle_t) transfer;
    586623
Note: See TracChangeset for help on using the changeset viewer.