Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/remote_usbhc.c

    r93f8da1 r6427cf67  
    3333 */
    3434
    35 #include <ipc/ipc.h>
    3635#include <async.h>
    3736#include <errno.h>
     
    4342
    4443static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    45 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4644static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4745static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    6563        remote_usbhc_get_address,
    6664
    67         remote_usbhc_get_buffer,
    68 
    6965        remote_usbhc_reserve_default_address,
    7066        remote_usbhc_release_default_address,
     
    9995typedef struct {
    10096        ipc_callid_t caller;
     97        ipc_callid_t data_caller;
    10198        void *buffer;
    10299        void *setup_packet;
     
    128125
    129126        trans->caller = caller;
     127        trans->data_caller = 0;
    130128        trans->buffer = NULL;
    131129        trans->setup_packet = NULL;
     
    141139
    142140        if (!usb_iface->tell_address) {
    143                 ipc_answer_0(callid, ENOTSUP);
     141                async_answer_0(callid, ENOTSUP);
    144142                return;
    145143        }
     
    150148        int rc = usb_iface->tell_address(device, handle, &address);
    151149        if (rc != EOK) {
    152                 ipc_answer_0(callid, rc);
     150                async_answer_0(callid, rc);
    153151        } else {
    154                 ipc_answer_1(callid, EOK, address);
    155         }
    156 }
    157 
    158 void remote_usbhc_get_buffer(device_t *device, void *iface,
    159     ipc_callid_t callid, ipc_call_t *call)
    160 {
    161         sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call);
    162         async_transaction_t * trans = (async_transaction_t *)buffer_hash;
    163         if (trans == NULL) {
    164                 ipc_answer_0(callid, ENOENT);
    165                 return;
    166         }
    167         if (trans->buffer == NULL) {
    168                 ipc_answer_0(callid, EINVAL);
    169                 async_transaction_destroy(trans);
    170                 return;
    171         }
    172 
    173         ipc_callid_t cid;
    174         size_t accepted_size;
    175         if (!async_data_read_receive(&cid, &accepted_size)) {
    176                 ipc_answer_0(callid, EINVAL);
    177                 async_transaction_destroy(trans);
    178                 return;
    179         }
    180 
    181         if (accepted_size > trans->size) {
    182                 accepted_size = trans->size;
    183         }
    184         async_data_read_finalize(cid, trans->buffer, accepted_size);
    185 
    186         ipc_answer_1(callid, EOK, accepted_size);
    187 
    188         async_transaction_destroy(trans);
     152                async_answer_1(callid, EOK, address);
     153        }
    189154}
    190155
     
    195160
    196161        if (!usb_iface->reserve_default_address) {
    197                 ipc_answer_0(callid, ENOTSUP);
    198                 return;
    199         }
    200 
    201         int rc = usb_iface->reserve_default_address(device);
    202 
    203         ipc_answer_0(callid, rc);
     162                async_answer_0(callid, ENOTSUP);
     163                return;
     164        }
     165       
     166        bool full_speed = DEV_IPC_GET_ARG1(*call);
     167       
     168        int rc = usb_iface->reserve_default_address(device, full_speed);
     169
     170        async_answer_0(callid, rc);
    204171}
    205172
     
    210177
    211178        if (!usb_iface->release_default_address) {
    212                 ipc_answer_0(callid, ENOTSUP);
     179                async_answer_0(callid, ENOTSUP);
    213180                return;
    214181        }
     
    216183        int rc = usb_iface->release_default_address(device);
    217184
    218         ipc_answer_0(callid, rc);
     185        async_answer_0(callid, rc);
    219186}
    220187
     
    225192
    226193        if (!usb_iface->request_address) {
    227                 ipc_answer_0(callid, ENOTSUP);
    228                 return;
    229         }
     194                async_answer_0(callid, ENOTSUP);
     195                return;
     196        }
     197       
     198        bool full_speed = DEV_IPC_GET_ARG1(*call);
    230199
    231200        usb_address_t address;
    232         int rc = usb_iface->request_address(device, &address);
    233         if (rc != EOK) {
    234                 ipc_answer_0(callid, rc);
     201        int rc = usb_iface->request_address(device, full_speed, &address);
     202        if (rc != EOK) {
     203                async_answer_0(callid, rc);
    235204        } else {
    236                 ipc_answer_1(callid, EOK, (sysarg_t) address);
     205                async_answer_1(callid, EOK, (sysarg_t) address);
    237206        }
    238207}
     
    244213
    245214        if (!usb_iface->bind_address) {
    246                 ipc_answer_0(callid, ENOTSUP);
     215                async_answer_0(callid, ENOTSUP);
    247216                return;
    248217        }
     
    253222        int rc = usb_iface->bind_address(device, address, handle);
    254223
    255         ipc_answer_0(callid, rc);
     224        async_answer_0(callid, rc);
    256225}
    257226
     
    262231
    263232        if (!usb_iface->release_address) {
    264                 ipc_answer_0(callid, ENOTSUP);
     233                async_answer_0(callid, ENOTSUP);
    265234                return;
    266235        }
     
    270239        int rc = usb_iface->release_address(device, address);
    271240
    272         ipc_answer_0(callid, rc);
     241        async_answer_0(callid, rc);
    273242}
    274243
    275244
    276245static void callback_out(device_t *device,
    277     usb_transaction_outcome_t outcome, void *arg)
     246    int outcome, void *arg)
    278247{
    279248        async_transaction_t *trans = (async_transaction_t *)arg;
    280249
    281         ipc_answer_0(trans->caller, outcome);
     250        async_answer_0(trans->caller, outcome);
    282251
    283252        async_transaction_destroy(trans);
     
    285254
    286255static void callback_in(device_t *device,
    287     usb_transaction_outcome_t outcome, size_t actual_size, void *arg)
     256    int outcome, size_t actual_size, void *arg)
    288257{
    289258        async_transaction_t *trans = (async_transaction_t *)arg;
    290259
    291         if (outcome != USB_OUTCOME_OK) {
    292                 ipc_answer_0(trans->caller, outcome);
     260        if (outcome != EOK) {
     261                async_answer_0(trans->caller, outcome);
     262                if (trans->data_caller) {
     263                        async_answer_0(trans->data_caller, EINTR);
     264                }
    293265                async_transaction_destroy(trans);
    294266                return;
     
    296268
    297269        trans->size = actual_size;
    298         ipc_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans);
     270
     271        if (trans->data_caller) {
     272                async_data_read_finalize(trans->data_caller,
     273                    trans->buffer, actual_size);
     274        }
     275
     276        async_answer_0(trans->caller, EOK);
     277
     278        async_transaction_destroy(trans);
    299279}
    300280
     
    311291{
    312292        if (!transfer_func) {
    313                 ipc_answer_0(callid, ENOTSUP);
     293                async_answer_0(callid, ENOTSUP);
    314294                return;
    315295        }
     
    329309
    330310                if (rc != EOK) {
    331                         ipc_answer_0(callid, rc);
     311                        async_answer_0(callid, rc);
    332312                        return;
    333313                }
     
    339319                        free(buffer);
    340320                }
    341                 ipc_answer_0(callid, ENOMEM);
     321                async_answer_0(callid, ENOMEM);
    342322                return;
    343323        }
     
    350330
    351331        if (rc != EOK) {
    352                 ipc_answer_0(callid, rc);
     332                async_answer_0(callid, rc);
    353333                async_transaction_destroy(trans);
    354334        }
     
    367347{
    368348        if (!transfer_func) {
    369                 ipc_answer_0(callid, ENOTSUP);
     349                async_answer_0(callid, ENOTSUP);
    370350                return;
    371351        }
     
    377357        };
    378358
     359        ipc_callid_t data_callid;
     360        if (!async_data_read_receive(&data_callid, &len)) {
     361                async_answer_0(callid, EPARTY);
     362                return;
     363        }
     364
    379365        async_transaction_t *trans = async_transaction_create(callid);
    380366        if (trans == NULL) {
    381                 ipc_answer_0(callid, ENOMEM);
    382                 return;
    383         }
     367                async_answer_0(callid, ENOMEM);
     368                return;
     369        }
     370        trans->data_caller = data_callid;
    384371        trans->buffer = malloc(len);
    385372        trans->size = len;
     
    389376
    390377        if (rc != EOK) {
    391                 ipc_answer_0(callid, rc);
     378                async_answer_0(callid, rc);
    392379                async_transaction_destroy(trans);
    393380        }
     
    414401                case USB_DIRECTION_IN:
    415402                        if (!transfer_in_func) {
    416                                 ipc_answer_0(callid, ENOTSUP);
     403                                async_answer_0(callid, ENOTSUP);
    417404                                return;
    418405                        }
     
    420407                case USB_DIRECTION_OUT:
    421408                        if (!transfer_out_func) {
    422                                 ipc_answer_0(callid, ENOTSUP);
     409                                async_answer_0(callid, ENOTSUP);
    423410                                return;
    424411                        }
     
    436423        async_transaction_t *trans = async_transaction_create(callid);
    437424        if (trans == NULL) {
    438                 ipc_answer_0(callid, ENOMEM);
     425                async_answer_0(callid, ENOMEM);
    439426                return;
    440427        }
     
    456443
    457444        if (rc != EOK) {
    458                 ipc_answer_0(callid, rc);
     445                async_answer_0(callid, rc);
    459446                async_transaction_destroy(trans);
    460447        }
     
    549536
    550537        if (!usb_iface->control_write) {
    551                 ipc_answer_0(callid, ENOTSUP);
     538                async_answer_0(callid, ENOTSUP);
    552539                return;
    553540        }
     
    557544                .endpoint = DEV_IPC_GET_ARG2(*call)
    558545        };
     546        size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
    559547
    560548        int rc;
     
    563551        void *data_buffer = NULL;
    564552        size_t setup_packet_len = 0;
    565         size_t data_buffer_len = 0;
    566553
    567554        rc = async_data_write_accept(&setup_packet, false,
    568555            1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len);
    569556        if (rc != EOK) {
    570                 ipc_answer_0(callid, rc);
    571                 return;
    572         }
    573         rc = async_data_write_accept(&data_buffer, false,
    574             1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len);
    575         if (rc != EOK) {
    576                 ipc_answer_0(callid, rc);
    577                 free(setup_packet);
    578                 return;
     557                async_answer_0(callid, rc);
     558                return;
     559        }
     560
     561        if (data_buffer_len > 0) {
     562                rc = async_data_write_accept(&data_buffer, false,
     563                    1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len);
     564                if (rc != EOK) {
     565                        async_answer_0(callid, rc);
     566                        free(setup_packet);
     567                        return;
     568                }
    579569        }
    580570
    581571        async_transaction_t *trans = async_transaction_create(callid);
    582572        if (trans == NULL) {
    583                 ipc_answer_0(callid, ENOMEM);
     573                async_answer_0(callid, ENOMEM);
    584574                free(setup_packet);
    585575                free(data_buffer);
     
    596586
    597587        if (rc != EOK) {
    598                 ipc_answer_0(callid, rc);
     588                async_answer_0(callid, rc);
    599589                async_transaction_destroy(trans);
    600590        }
     
    609599
    610600        if (!usb_iface->control_read) {
    611                 ipc_answer_0(callid, ENOTSUP);
    612                 return;
    613         }
    614 
    615         size_t data_len = DEV_IPC_GET_ARG3(*call);
     601                async_answer_0(callid, ENOTSUP);
     602                return;
     603        }
     604
    616605        usb_target_t target = {
    617606                .address = DEV_IPC_GET_ARG1(*call),
     
    623612        void *setup_packet = NULL;
    624613        size_t setup_packet_len = 0;
     614        size_t data_len = 0;
    625615
    626616        rc = async_data_write_accept(&setup_packet, false,
    627617            1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len);
    628618        if (rc != EOK) {
    629                 ipc_answer_0(callid, rc);
     619                async_answer_0(callid, rc);
     620                return;
     621        }
     622
     623        ipc_callid_t data_callid;
     624        if (!async_data_read_receive(&data_callid, &data_len)) {
     625                async_answer_0(callid, EPARTY);
     626                free(setup_packet);
    630627                return;
    631628        }
     
    633630        async_transaction_t *trans = async_transaction_create(callid);
    634631        if (trans == NULL) {
    635                 ipc_answer_0(callid, ENOMEM);
     632                async_answer_0(callid, ENOMEM);
    636633                free(setup_packet);
    637634                return;
    638635        }
     636        trans->data_caller = data_callid;
    639637        trans->setup_packet = setup_packet;
    640638        trans->size = data_len;
    641639        trans->buffer = malloc(data_len);
    642640        if (trans->buffer == NULL) {
    643                 ipc_answer_0(callid, ENOMEM);
     641                async_answer_0(callid, ENOMEM);
    644642                async_transaction_destroy(trans);
    645643                return;
     
    652650
    653651        if (rc != EOK) {
    654                 ipc_answer_0(callid, rc);
     652                async_answer_0(callid, rc);
    655653                async_transaction_destroy(trans);
    656654        }
Note: See TracChangeset for help on using the changeset viewer.