Changeset 1968de5 in mainline


Ignore:
Timestamp:
2011-02-11T16:27:45Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
608afb9
Parents:
03197ffc (diff), 5842493 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merged get_buffer request removal (ticket 54)

Location:
uspace/lib
Files:
5 edited

Legend:

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

    r03197ffc r1968de5  
    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 */
     1577aid_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
    15691583/** Wrapper for IPC_M_DATA_READ calls using the async framework.
    15701584 *
  • uspace/lib/c/include/async.h

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

    r03197ffc r1968de5  
    4242
    4343static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    44 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4544static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4645static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    6463        remote_usbhc_get_address,
    6564
    66         remote_usbhc_get_buffer,
    67 
    6865        remote_usbhc_reserve_default_address,
    6966        remote_usbhc_release_default_address,
     
    9895typedef struct {
    9996        ipc_callid_t caller;
     97        ipc_callid_t data_caller;
    10098        void *buffer;
    10199        void *setup_packet;
     
    127125
    128126        trans->caller = caller;
     127        trans->data_caller = 0;
    129128        trans->buffer = NULL;
    130129        trans->setup_packet = NULL;
     
    155154}
    156155
    157 void 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 
    190156void remote_usbhc_reserve_default_address(device_t *device, void *iface,
    191157    ipc_callid_t callid, ipc_call_t *call)
     
    290256        if (outcome != USB_OUTCOME_OK) {
    291257                async_answer_0(trans->caller, outcome);
     258                if (trans->data_caller) {
     259                        async_answer_0(trans->data_caller, EINTR);
     260                }
    292261                async_transaction_destroy(trans);
    293262                return;
     
    295264
    296265        trans->size = actual_size;
    297         async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans);
     266
     267        if (trans->data_caller) {
     268                async_data_read_finalize(trans->data_caller,
     269                    trans->buffer, actual_size);
     270        }
     271
     272        async_answer_0(trans->caller, USB_OUTCOME_OK);
     273
     274        async_transaction_destroy(trans);
    298275}
    299276
     
    376353        };
    377354
     355        ipc_callid_t data_callid;
     356        if (!async_data_read_receive(&data_callid, &len)) {
     357                async_answer_0(callid, EPARTY);
     358                return;
     359        }
     360
    378361        async_transaction_t *trans = async_transaction_create(callid);
    379362        if (trans == NULL) {
     
    381364                return;
    382365        }
     366        trans->data_caller = data_callid;
    383367        trans->buffer = malloc(len);
    384368        trans->size = len;
     
    630614        }
    631615
     616        ipc_callid_t data_callid;
     617        if (!async_data_read_receive(&data_callid, &data_len)) {
     618                async_answer_0(callid, EPARTY);
     619                free(setup_packet);
     620                return;
     621        }
     622
    632623        async_transaction_t *trans = async_transaction_create(callid);
    633624        if (trans == NULL) {
     
    636627                return;
    637628        }
     629        trans->data_caller = data_callid;
    638630        trans->setup_packet = setup_packet;
    639631        trans->size = data_len;
  • uspace/lib/drv/include/usbhc_iface.h

    r03197ffc r1968de5  
    6666 *   - argument #2 is target endpoint
    6767 *   - argument #3 is buffer size
     68 * - this call is immediately followed by IPC data read (async version)
    6869 * - the call is not answered until the device returns some data (or until
    6970 *   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
    7271 *
    7372 * Some special methods (NO-DATA transactions) do not send any data. These
    7473 * might behave as both OUT or IN transactions because communication parts
    7574 * where actual buffers are exchanged are omitted.
    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  *
     75 **
    8576 * For all these methods, wrap functions exists. Important rule: functions
    8677 * for IN transactions have (as parameters) buffers where retrieved data
     
    10495        IPC_M_USBHC_GET_ADDRESS,
    10596
    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 
    11397
    11498        /** Reserve usage of default address.
  • uspace/lib/usb/src/usbdrv.c

    r03197ffc r1968de5  
    4949        /** Storage for actual number of bytes transferred. */
    5050        size_t *size_transferred;
    51         /** Initial call replay data. */
     51        /** Initial call reply 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;
    5559} transfer_info_t;
    5660
     
    140144
    141145        if (rc != EOK) {
    142                 printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc));
    143146                return rc;
    144147        }
     
    250253        }
    251254
     255        transfer->read_request = 0;
    252256        transfer->size_transferred = NULL;
    253257        transfer->buffer = NULL;
     
    315319        }
    316320
     321        transfer->read_request = 0;
    317322        transfer->size_transferred = actual_size;
    318323        transfer->buffer = buffer;
     
    327332            &transfer->reply);
    328333
     334        if (buffer != NULL) {
     335                transfer->read_request = async_data_read(phone, buffer, size,
     336                    &transfer->read_reply);
     337        }
     338
    329339        *handle = (usb_handle_t) transfer;
    330340
     
    332342}
    333343
    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  */
    344 static 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 }
    375344
    376345/** Blocks caller until given USB transaction is finished.
     
    395364
    396365        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         }
    403366
    404367        /*
     
    406369         */
    407370        if ((transfer->buffer != NULL) && (transfer->size > 0)) {
    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;
     371                async_wait_for(transfer->read_request, &answer_rc);
     372
     373                if (answer_rc != EOK) {
     374                        rc = (int) answer_rc;
    416375                        goto leave;
    417376                }
    418377
    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;
     378                if (transfer->size_transferred != NULL) {
     379                        *(transfer->size_transferred)
     380                            = IPC_GET_ARG2(transfer->read_reply);
    425381                }
    426 
    427                 if (transfer->size_transferred) {
    428                         *(transfer->size_transferred) = actual_size;
    429                 }
     382        }
     383
     384        async_wait_for(transfer->request, &answer_rc);
     385
     386        if (answer_rc != EOK) {
     387                rc = (int) answer_rc;
     388                goto leave;
    430389        }
    431390
     
    515474        }
    516475
     476        transfer->read_request = 0;
    517477        transfer->size_transferred = NULL;
    518478        transfer->buffer = NULL;
     
    620580        }
    621581
     582        transfer->read_request = async_data_read(phone, buffer, buffer_size,
     583            &transfer->read_reply);
     584
    622585        *handle = (usb_handle_t) transfer;
    623586
Note: See TracChangeset for help on using the changeset viewer.