Ignore:
Timestamp:
2011-02-24T12:03:27Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e7b7ebd5
Parents:
4837092 (diff), a80849c (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 development (changes in DDF, etc.).

Conflicts in uspace/drv/usbkbd/main.c

File:
1 edited

Legend:

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

    r4837092 r92574f4  
    3333 */
    3434
    35 #include <ipc/ipc.h>
    3635#include <async.h>
    3736#include <errno.h>
     37#include <assert.h>
    3838
    3939#include "usbhc_iface.h"
    40 #include "driver.h"
     40#include "ddf/driver.h"
    4141
    4242#define USB_MAX_PAYLOAD_SIZE 1020
    43 
    44 static 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 *);
    46 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    47 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
    48 static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
    49 static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
    50 static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
    51 static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
    52 static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
    53 static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
    54 static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
    55 static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
    56 static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    57 static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    58 static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    59 static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    60 static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    61 //static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *);
     43#define HACK_MAX_PACKET_SIZE 8
     44#define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4
     45
     46static void remote_usbhc_interrupt_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     47static void remote_usbhc_interrupt_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     48static void remote_usbhc_bulk_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     49static void remote_usbhc_bulk_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     50static void remote_usbhc_control_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     51static void remote_usbhc_control_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     52static void remote_usbhc_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     53static void remote_usbhc_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     54static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     55static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     56static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     57//static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    6258
    6359/** Remote USB host controller interface operations. */
    6460static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
    65         remote_usbhc_get_address,
    66 
    67         remote_usbhc_get_buffer,
    68 
    6961        remote_usbhc_reserve_default_address,
    7062        remote_usbhc_release_default_address,
     
    7769        remote_usbhc_interrupt_in,
    7870
    79         remote_usbhc_control_write_setup,
    80         remote_usbhc_control_write_data,
    81         remote_usbhc_control_write_status,
    82 
    83         remote_usbhc_control_read_setup,
    84         remote_usbhc_control_read_data,
    85         remote_usbhc_control_read_status,
     71        remote_usbhc_bulk_out,
     72        remote_usbhc_bulk_in,
    8673
    8774        remote_usbhc_control_write,
     
    9986typedef struct {
    10087        ipc_callid_t caller;
     88        ipc_callid_t data_caller;
    10189        void *buffer;
    10290        void *setup_packet;
     
    128116
    129117        trans->caller = caller;
     118        trans->data_caller = 0;
    130119        trans->buffer = NULL;
    131120        trans->setup_packet = NULL;
     
    135124}
    136125
    137 void remote_usbhc_get_address(device_t *device, void *iface,
    138     ipc_callid_t callid, ipc_call_t *call)
    139 {
    140         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    141 
    142         if (!usb_iface->tell_address) {
    143                 ipc_answer_0(callid, ENOTSUP);
    144                 return;
    145         }
    146 
    147         devman_handle_t handle = DEV_IPC_GET_ARG1(*call);
     126void remote_usbhc_reserve_default_address(ddf_fun_t *fun, void *iface,
     127    ipc_callid_t callid, ipc_call_t *call)
     128{
     129        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     130
     131        if (!usb_iface->reserve_default_address) {
     132                async_answer_0(callid, ENOTSUP);
     133                return;
     134        }
     135       
     136        usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
     137       
     138        int rc = usb_iface->reserve_default_address(fun, speed);
     139
     140        async_answer_0(callid, rc);
     141}
     142
     143void remote_usbhc_release_default_address(ddf_fun_t *fun, void *iface,
     144    ipc_callid_t callid, ipc_call_t *call)
     145{
     146        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     147
     148        if (!usb_iface->release_default_address) {
     149                async_answer_0(callid, ENOTSUP);
     150                return;
     151        }
     152
     153        int rc = usb_iface->release_default_address(fun);
     154
     155        async_answer_0(callid, rc);
     156}
     157
     158void remote_usbhc_request_address(ddf_fun_t *fun, void *iface,
     159    ipc_callid_t callid, ipc_call_t *call)
     160{
     161        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     162
     163        if (!usb_iface->request_address) {
     164                async_answer_0(callid, ENOTSUP);
     165                return;
     166        }
     167       
     168        usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
    148169
    149170        usb_address_t address;
    150         int rc = usb_iface->tell_address(device, handle, &address);
    151         if (rc != EOK) {
    152                 ipc_answer_0(callid, rc);
     171        int rc = usb_iface->request_address(fun, speed, &address);
     172        if (rc != EOK) {
     173                async_answer_0(callid, rc);
    153174        } 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);
    189 }
    190 
    191 void remote_usbhc_reserve_default_address(device_t *device, void *iface,
    192     ipc_callid_t callid, ipc_call_t *call)
    193 {
    194         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    195 
    196         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);
    204 }
    205 
    206 void remote_usbhc_release_default_address(device_t *device, void *iface,
    207     ipc_callid_t callid, ipc_call_t *call)
    208 {
    209         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    210 
    211         if (!usb_iface->release_default_address) {
    212                 ipc_answer_0(callid, ENOTSUP);
    213                 return;
    214         }
    215 
    216         int rc = usb_iface->release_default_address(device);
    217 
    218         ipc_answer_0(callid, rc);
    219 }
    220 
    221 void remote_usbhc_request_address(device_t *device, void *iface,
    222     ipc_callid_t callid, ipc_call_t *call)
    223 {
    224         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    225 
    226         if (!usb_iface->request_address) {
    227                 ipc_answer_0(callid, ENOTSUP);
    228                 return;
    229         }
    230 
    231         usb_address_t address;
    232         int rc = usb_iface->request_address(device, &address);
    233         if (rc != EOK) {
    234                 ipc_answer_0(callid, rc);
    235         } else {
    236                 ipc_answer_1(callid, EOK, (sysarg_t) address);
    237         }
    238 }
    239 
    240 void remote_usbhc_bind_address(device_t *device, void *iface,
     175                async_answer_1(callid, EOK, (sysarg_t) address);
     176        }
     177}
     178
     179void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface,
    241180    ipc_callid_t callid, ipc_call_t *call)
    242181{
     
    244183
    245184        if (!usb_iface->bind_address) {
    246                 ipc_answer_0(callid, ENOTSUP);
     185                async_answer_0(callid, ENOTSUP);
    247186                return;
    248187        }
     
    251190        devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call);
    252191
    253         int rc = usb_iface->bind_address(device, address, handle);
    254 
    255         ipc_answer_0(callid, rc);
    256 }
    257 
    258 void remote_usbhc_release_address(device_t *device, void *iface,
     192        int rc = usb_iface->bind_address(fun, address, handle);
     193
     194        async_answer_0(callid, rc);
     195}
     196
     197void remote_usbhc_release_address(ddf_fun_t *fun, void *iface,
    259198    ipc_callid_t callid, ipc_call_t *call)
    260199{
     
    262201
    263202        if (!usb_iface->release_address) {
    264                 ipc_answer_0(callid, ENOTSUP);
     203                async_answer_0(callid, ENOTSUP);
    265204                return;
    266205        }
     
    268207        usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
    269208
    270         int rc = usb_iface->release_address(device, address);
    271 
    272         ipc_answer_0(callid, rc);
    273 }
    274 
    275 
    276 static void callback_out(device_t *device,
    277     usb_transaction_outcome_t outcome, void *arg)
     209        int rc = usb_iface->release_address(fun, address);
     210
     211        async_answer_0(callid, rc);
     212}
     213
     214
     215static void callback_out(ddf_fun_t *fun,
     216    int outcome, void *arg)
    278217{
    279218        async_transaction_t *trans = (async_transaction_t *)arg;
    280219
    281         ipc_answer_0(trans->caller, outcome);
     220        async_answer_0(trans->caller, outcome);
    282221
    283222        async_transaction_destroy(trans);
    284223}
    285224
    286 static void callback_in(device_t *device,
    287     usb_transaction_outcome_t outcome, size_t actual_size, void *arg)
     225static void callback_in(ddf_fun_t *fun,
     226    int outcome, size_t actual_size, void *arg)
    288227{
    289228        async_transaction_t *trans = (async_transaction_t *)arg;
    290229
    291         if (outcome != USB_OUTCOME_OK) {
    292                 ipc_answer_0(trans->caller, outcome);
     230        if (outcome != EOK) {
     231                async_answer_0(trans->caller, outcome);
     232                if (trans->data_caller) {
     233                        async_answer_0(trans->data_caller, EINTR);
     234                }
    293235                async_transaction_destroy(trans);
    294236                return;
     
    296238
    297239        trans->size = actual_size;
    298         ipc_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans);
     240
     241        if (trans->data_caller) {
     242                async_data_read_finalize(trans->data_caller,
     243                    trans->buffer, actual_size);
     244        }
     245
     246        async_answer_0(trans->caller, EOK);
     247
     248        async_transaction_destroy(trans);
    299249}
    300250
     
    306256 * @param transfer_func Transfer function (might be NULL).
    307257 */
    308 static void remote_usbhc_out_transfer(device_t *device,
     258static void remote_usbhc_out_transfer(ddf_fun_t *fun,
    309259    ipc_callid_t callid, ipc_call_t *call,
    310260    usbhc_iface_transfer_out_t transfer_func)
    311261{
    312262        if (!transfer_func) {
    313                 ipc_answer_0(callid, ENOTSUP);
    314                 return;
    315         }
    316 
    317         size_t expected_len = DEV_IPC_GET_ARG3(*call);
     263                async_answer_0(callid, ENOTSUP);
     264                return;
     265        }
     266
     267        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    318268        usb_target_t target = {
    319269                .address = DEV_IPC_GET_ARG1(*call),
     
    323273        size_t len = 0;
    324274        void *buffer = NULL;
    325         if (expected_len > 0) {
    326                 int rc = async_data_write_accept(&buffer, false,
    327                     1, USB_MAX_PAYLOAD_SIZE,
    328                     0, &len);
    329 
    330                 if (rc != EOK) {
    331                         ipc_answer_0(callid, rc);
    332                         return;
    333                 }
     275
     276        int rc = async_data_write_accept(&buffer, false,
     277            1, USB_MAX_PAYLOAD_SIZE,
     278            0, &len);
     279
     280        if (rc != EOK) {
     281                async_answer_0(callid, rc);
     282                return;
    334283        }
    335284
     
    339288                        free(buffer);
    340289                }
    341                 ipc_answer_0(callid, ENOMEM);
     290                async_answer_0(callid, ENOMEM);
    342291                return;
    343292        }
     
    346295        trans->size = len;
    347296
    348         int rc = transfer_func(device, target, buffer, len,
     297        rc = transfer_func(fun, target, max_packet_size,
     298            buffer, len,
    349299            callback_out, trans);
    350300
    351301        if (rc != EOK) {
    352                 ipc_answer_0(callid, rc);
     302                async_answer_0(callid, rc);
    353303                async_transaction_destroy(trans);
    354304        }
     
    362312 * @param transfer_func Transfer function (might be NULL).
    363313 */
    364 static void remote_usbhc_in_transfer(device_t *device,
     314static void remote_usbhc_in_transfer(ddf_fun_t *fun,
    365315    ipc_callid_t callid, ipc_call_t *call,
    366316    usbhc_iface_transfer_in_t transfer_func)
    367317{
    368318        if (!transfer_func) {
    369                 ipc_answer_0(callid, ENOTSUP);
    370                 return;
    371         }
    372 
    373         size_t len = DEV_IPC_GET_ARG3(*call);
     319                async_answer_0(callid, ENOTSUP);
     320                return;
     321        }
     322
     323        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    374324        usb_target_t target = {
    375325                .address = DEV_IPC_GET_ARG1(*call),
     
    377327        };
    378328
     329        size_t len;
     330        ipc_callid_t data_callid;
     331        if (!async_data_read_receive(&data_callid, &len)) {
     332                async_answer_0(callid, EPARTY);
     333                return;
     334        }
     335
    379336        async_transaction_t *trans = async_transaction_create(callid);
    380337        if (trans == NULL) {
    381                 ipc_answer_0(callid, ENOMEM);
    382                 return;
    383         }
     338                async_answer_0(callid, ENOMEM);
     339                return;
     340        }
     341        trans->data_caller = data_callid;
    384342        trans->buffer = malloc(len);
    385343        trans->size = len;
    386344
    387         int rc = transfer_func(device, target, trans->buffer, len,
     345        int rc = transfer_func(fun, target, max_packet_size,
     346            trans->buffer, len,
    388347            callback_in, trans);
    389348
    390349        if (rc != EOK) {
    391                 ipc_answer_0(callid, rc);
     350                async_answer_0(callid, rc);
    392351                async_transaction_destroy(trans);
    393352        }
    394353}
    395354
    396 /** Process status part of control transfer.
    397  *
    398  * @param device Target device.
    399  * @param callid Initiating caller.
    400  * @param call Initiating call.
    401  * @param direction Transfer direction (read ~ in, write ~ out).
    402  * @param transfer_in_func Transfer function for control read (might be NULL).
    403  * @param transfer_out_func Transfer function for control write (might be NULL).
    404  */
    405 static void remote_usbhc_status_transfer(device_t *device,
    406     ipc_callid_t callid, ipc_call_t *call,
    407     usb_direction_t direction,
    408     int (*transfer_in_func)(device_t *, usb_target_t,
    409         usbhc_iface_transfer_in_callback_t, void *),
    410     int (*transfer_out_func)(device_t *, usb_target_t,
    411         usbhc_iface_transfer_out_callback_t, void *))
    412 {
    413         switch (direction) {
    414                 case USB_DIRECTION_IN:
    415                         if (!transfer_in_func) {
    416                                 ipc_answer_0(callid, ENOTSUP);
    417                                 return;
    418                         }
    419                         break;
    420                 case USB_DIRECTION_OUT:
    421                         if (!transfer_out_func) {
    422                                 ipc_answer_0(callid, ENOTSUP);
    423                                 return;
    424                         }
    425                         break;
    426                 default:
    427                         assert(false && "unreachable code");
    428                         break;
     355void remote_usbhc_interrupt_out(ddf_fun_t *fun, void *iface,
     356    ipc_callid_t callid, ipc_call_t *call)
     357{
     358        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     359        assert(usb_iface != NULL);
     360
     361        return remote_usbhc_out_transfer(fun, callid, call,
     362            usb_iface->interrupt_out);
     363}
     364
     365void remote_usbhc_interrupt_in(ddf_fun_t *fun, void *iface,
     366    ipc_callid_t callid, ipc_call_t *call)
     367{
     368        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     369        assert(usb_iface != NULL);
     370
     371        return remote_usbhc_in_transfer(fun, callid, call,
     372            usb_iface->interrupt_in);
     373}
     374
     375void remote_usbhc_bulk_out(ddf_fun_t *fun, void *iface,
     376    ipc_callid_t callid, ipc_call_t *call)
     377{
     378        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     379        assert(usb_iface != NULL);
     380
     381        return remote_usbhc_out_transfer(fun, callid, call,
     382            usb_iface->bulk_out);
     383}
     384
     385void remote_usbhc_bulk_in(ddf_fun_t *fun, void *iface,
     386    ipc_callid_t callid, ipc_call_t *call)
     387{
     388        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     389        assert(usb_iface != NULL);
     390
     391        return remote_usbhc_in_transfer(fun, callid, call,
     392            usb_iface->bulk_in);
     393}
     394
     395void remote_usbhc_control_write(ddf_fun_t *fun, void *iface,
     396ipc_callid_t callid, ipc_call_t *call)
     397{
     398        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     399        assert(usb_iface != NULL);
     400
     401        if (!usb_iface->control_write) {
     402                async_answer_0(callid, ENOTSUP);
     403                return;
    429404        }
    430405
     
    433408                .endpoint = DEV_IPC_GET_ARG2(*call)
    434409        };
     410        size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
     411        size_t max_packet_size = DEV_IPC_GET_ARG4(*call);
     412
     413        int rc;
     414
     415        void *setup_packet = NULL;
     416        void *data_buffer = NULL;
     417        size_t setup_packet_len = 0;
     418
     419        rc = async_data_write_accept(&setup_packet, false,
     420            1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len);
     421        if (rc != EOK) {
     422                async_answer_0(callid, rc);
     423                return;
     424        }
     425
     426        if (data_buffer_len > 0) {
     427                rc = async_data_write_accept(&data_buffer, false,
     428                    1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len);
     429                if (rc != EOK) {
     430                        async_answer_0(callid, rc);
     431                        free(setup_packet);
     432                        return;
     433                }
     434        }
    435435
    436436        async_transaction_t *trans = async_transaction_create(callid);
    437437        if (trans == NULL) {
    438                 ipc_answer_0(callid, ENOMEM);
    439                 return;
    440         }
    441 
    442         int rc;
    443         switch (direction) {
    444                 case USB_DIRECTION_IN:
    445                         rc = transfer_in_func(device, target,
    446                             callback_in, trans);
    447                         break;
    448                 case USB_DIRECTION_OUT:
    449                         rc = transfer_out_func(device, target,
    450                             callback_out, trans);
    451                         break;
    452                 default:
    453                         assert(false && "unreachable code");
    454                         break;
    455         }
    456 
    457         if (rc != EOK) {
    458                 ipc_answer_0(callid, rc);
     438                async_answer_0(callid, ENOMEM);
     439                free(setup_packet);
     440                free(data_buffer);
     441                return;
     442        }
     443        trans->setup_packet = setup_packet;
     444        trans->buffer = data_buffer;
     445        trans->size = data_buffer_len;
     446
     447        rc = usb_iface->control_write(fun, target, max_packet_size,
     448            setup_packet, setup_packet_len,
     449            data_buffer, data_buffer_len,
     450            callback_out, trans);
     451
     452        if (rc != EOK) {
     453                async_answer_0(callid, rc);
    459454                async_transaction_destroy(trans);
    460455        }
     
    462457
    463458
    464 void remote_usbhc_interrupt_out(device_t *device, void *iface,
    465     ipc_callid_t callid, ipc_call_t *call)
     459void remote_usbhc_control_read(ddf_fun_t *fun, void *iface,
     460ipc_callid_t callid, ipc_call_t *call)
    466461{
    467462        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    468463        assert(usb_iface != NULL);
    469464
    470         return remote_usbhc_out_transfer(device, callid, call,
    471             usb_iface->interrupt_out);
    472 }
    473 
    474 void remote_usbhc_interrupt_in(device_t *device, void *iface,
    475     ipc_callid_t callid, ipc_call_t *call)
    476 {
    477         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    478         assert(usb_iface != NULL);
    479 
    480         return remote_usbhc_in_transfer(device, callid, call,
    481             usb_iface->interrupt_in);
    482 }
    483 
    484 void remote_usbhc_control_write_setup(device_t *device, void *iface,
    485     ipc_callid_t callid, ipc_call_t *call)
    486 {
    487         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    488         assert(usb_iface != NULL);
    489 
    490         return remote_usbhc_out_transfer(device, callid, call,
    491             usb_iface->control_write_setup);
    492 }
    493 
    494 void remote_usbhc_control_write_data(device_t *device, void *iface,
    495     ipc_callid_t callid, ipc_call_t *call)
    496 {
    497         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    498         assert(usb_iface != NULL);
    499 
    500         return remote_usbhc_out_transfer(device, callid, call,
    501             usb_iface->control_write_data);
    502 }
    503 
    504 void remote_usbhc_control_write_status(device_t *device, void *iface,
    505     ipc_callid_t callid, ipc_call_t *call)
    506 {
    507         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    508         assert(usb_iface != NULL);
    509 
    510         return remote_usbhc_status_transfer(device, callid, call,
    511             USB_DIRECTION_IN, usb_iface->control_write_status, NULL);
    512 }
    513 
    514 void remote_usbhc_control_read_setup(device_t *device, void *iface,
    515     ipc_callid_t callid, ipc_call_t *call)
    516 {
    517         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    518         assert(usb_iface != NULL);
    519 
    520         return remote_usbhc_out_transfer(device, callid, call,
    521             usb_iface->control_read_setup);
    522 }
    523 
    524 void remote_usbhc_control_read_data(device_t *device, void *iface,
    525             ipc_callid_t callid, ipc_call_t *call)
    526 {
    527         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    528         assert(usb_iface != NULL);
    529 
    530         return remote_usbhc_in_transfer(device, callid, call,
    531             usb_iface->control_read_data);
    532 }
    533 
    534 void remote_usbhc_control_read_status(device_t *device, void *iface,
    535             ipc_callid_t callid, ipc_call_t *call)
    536 {
    537         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    538         assert(usb_iface != NULL);
    539 
    540         return remote_usbhc_status_transfer(device, callid, call,
    541             USB_DIRECTION_OUT, NULL, usb_iface->control_read_status);
    542 }
    543 
    544 void remote_usbhc_control_write(device_t *device, void *iface,
    545 ipc_callid_t callid, ipc_call_t *call)
    546 {
    547         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    548         assert(usb_iface != NULL);
    549 
    550         if (!usb_iface->control_write) {
    551                 ipc_answer_0(callid, ENOTSUP);
     465        if (!usb_iface->control_read) {
     466                async_answer_0(callid, ENOTSUP);
    552467                return;
    553468        }
     
    557472                .endpoint = DEV_IPC_GET_ARG2(*call)
    558473        };
     474        size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    559475
    560476        int rc;
    561477
    562478        void *setup_packet = NULL;
    563         void *data_buffer = NULL;
    564479        size_t setup_packet_len = 0;
    565         size_t data_buffer_len = 0;
     480        size_t data_len = 0;
    566481
    567482        rc = async_data_write_accept(&setup_packet, false,
    568483            1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len);
    569484        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);
     485                async_answer_0(callid, rc);
     486                return;
     487        }
     488
     489        ipc_callid_t data_callid;
     490        if (!async_data_read_receive(&data_callid, &data_len)) {
     491                async_answer_0(callid, EPARTY);
    577492                free(setup_packet);
    578493                return;
     
    581496        async_transaction_t *trans = async_transaction_create(callid);
    582497        if (trans == NULL) {
    583                 ipc_answer_0(callid, ENOMEM);
     498                async_answer_0(callid, ENOMEM);
    584499                free(setup_packet);
    585                 free(data_buffer);
    586                 return;
    587         }
    588         trans->setup_packet = setup_packet;
    589         trans->buffer = data_buffer;
    590         trans->size = data_buffer_len;
    591 
    592         rc = usb_iface->control_write(device, target,
    593             setup_packet, setup_packet_len,
    594             data_buffer, data_buffer_len,
    595             callback_out, trans);
    596 
    597         if (rc != EOK) {
    598                 ipc_answer_0(callid, rc);
    599                 async_transaction_destroy(trans);
    600         }
    601 }
    602 
    603 
    604 void remote_usbhc_control_read(device_t *device, void *iface,
    605 ipc_callid_t callid, ipc_call_t *call)
    606 {
    607         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    608         assert(usb_iface != NULL);
    609 
    610         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);
    616         usb_target_t target = {
    617                 .address = DEV_IPC_GET_ARG1(*call),
    618                 .endpoint = DEV_IPC_GET_ARG2(*call)
    619         };
    620 
    621         int rc;
    622 
    623         void *setup_packet = NULL;
    624         size_t setup_packet_len = 0;
    625 
    626         rc = async_data_write_accept(&setup_packet, false,
    627             1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len);
    628         if (rc != EOK) {
    629                 ipc_answer_0(callid, rc);
    630                 return;
    631         }
    632 
    633         async_transaction_t *trans = async_transaction_create(callid);
    634         if (trans == NULL) {
    635                 ipc_answer_0(callid, ENOMEM);
    636                 free(setup_packet);
    637                 return;
    638         }
     500                return;
     501        }
     502        trans->data_caller = data_callid;
    639503        trans->setup_packet = setup_packet;
    640504        trans->size = data_len;
    641505        trans->buffer = malloc(data_len);
    642506        if (trans->buffer == NULL) {
    643                 ipc_answer_0(callid, ENOMEM);
     507                async_answer_0(callid, ENOMEM);
    644508                async_transaction_destroy(trans);
    645509                return;
    646510        }
    647511
    648         rc = usb_iface->control_read(device, target,
     512        rc = usb_iface->control_read(fun, target, max_packet_size,
    649513            setup_packet, setup_packet_len,
    650514            trans->buffer, trans->size,
     
    652516
    653517        if (rc != EOK) {
    654                 ipc_answer_0(callid, rc);
     518                async_answer_0(callid, rc);
    655519                async_transaction_destroy(trans);
    656520        }
Note: See TracChangeset for help on using the changeset viewer.