Fork us on GitHub Follow us on Facebook Follow us on Twitter

Ignore:
Timestamp:
2010-12-05T09:34:46Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
Children:
75732da
Parents:
56b962d (diff), 35537a7 (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:

Merge with development/

File:
1 edited

Legend:

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

    r56b962d r84439d7  
    4242#define USB_MAX_PAYLOAD_SIZE 1020
    4343
     44static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4445static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4546static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4647static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
    47 //static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *);
     48static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
     49static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
     50static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
     51static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
     52static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
     53static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
     54static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     55static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     56static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     57static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     58static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     59//static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4860
    4961/** Remote USB interface operations. */
    5062static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
    51         &remote_usbhc_get_buffer,
    52         &remote_usbhc_interrupt_out,
    53         &remote_usbhc_interrupt_in
     63        remote_usbhc_get_address,
     64
     65        remote_usbhc_get_buffer,
     66
     67        remote_usbhc_reserve_default_address,
     68        remote_usbhc_release_default_address,
     69
     70        remote_usbhc_request_address,
     71        remote_usbhc_bind_address,
     72        remote_usbhc_release_address,
     73
     74        remote_usbhc_interrupt_out,
     75        remote_usbhc_interrupt_in,
     76
     77        remote_usbhc_control_write_setup,
     78        remote_usbhc_control_write_data,
     79        remote_usbhc_control_write_status,
     80
     81        remote_usbhc_control_read_setup,
     82        remote_usbhc_control_read_data,
     83        remote_usbhc_control_read_status
    5484};
    5585
     
    6898} async_transaction_t;
    6999
     100void remote_usbhc_get_address(device_t *device, void *iface,
     101    ipc_callid_t callid, ipc_call_t *call)
     102{
     103        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     104
     105        if (!usb_iface->tell_address) {
     106                ipc_answer_0(callid, ENOTSUP);
     107                return;
     108        }
     109
     110        devman_handle_t handle = IPC_GET_ARG1(*call);
     111
     112        usb_address_t address;
     113        int rc = usb_iface->tell_address(device, handle, &address);
     114        if (rc != EOK) {
     115                ipc_answer_0(callid, rc);
     116        } else {
     117                ipc_answer_1(callid, EOK, address);
     118        }
     119}
    70120
    71121void remote_usbhc_get_buffer(device_t *device, void *iface,
     
    102152}
    103153
     154void remote_usbhc_reserve_default_address(device_t *device, void *iface,
     155    ipc_callid_t callid, ipc_call_t *call)
     156{
     157        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     158
     159        if (!usb_iface->reserve_default_address) {
     160                ipc_answer_0(callid, ENOTSUP);
     161                return;
     162        }
     163
     164        int rc = usb_iface->reserve_default_address(device);
     165
     166        ipc_answer_0(callid, rc);
     167}
     168
     169void remote_usbhc_release_default_address(device_t *device, void *iface,
     170    ipc_callid_t callid, ipc_call_t *call)
     171{
     172        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     173
     174        if (!usb_iface->release_default_address) {
     175                ipc_answer_0(callid, ENOTSUP);
     176                return;
     177        }
     178
     179        int rc = usb_iface->release_default_address(device);
     180
     181        ipc_answer_0(callid, rc);
     182}
     183
     184void remote_usbhc_request_address(device_t *device, void *iface,
     185    ipc_callid_t callid, ipc_call_t *call)
     186{
     187        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     188
     189        if (!usb_iface->request_address) {
     190                ipc_answer_0(callid, ENOTSUP);
     191                return;
     192        }
     193
     194        usb_address_t address;
     195        int rc = usb_iface->request_address(device, &address);
     196        if (rc != EOK) {
     197                ipc_answer_0(callid, rc);
     198        } else {
     199                ipc_answer_1(callid, EOK, (ipcarg_t) address);
     200        }
     201}
     202
     203void remote_usbhc_bind_address(device_t *device, void *iface,
     204    ipc_callid_t callid, ipc_call_t *call)
     205{
     206        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     207
     208        if (!usb_iface->bind_address) {
     209                ipc_answer_0(callid, ENOTSUP);
     210                return;
     211        }
     212
     213        usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call);
     214        devman_handle_t handle = (devman_handle_t) IPC_GET_ARG2(*call);
     215
     216        int rc = usb_iface->bind_address(device, address, handle);
     217
     218        ipc_answer_0(callid, rc);
     219}
     220
     221void remote_usbhc_release_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->release_address) {
     227                ipc_answer_0(callid, ENOTSUP);
     228                return;
     229        }
     230
     231        usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call);
     232
     233        int rc = usb_iface->release_address(device, address);
     234
     235        ipc_answer_0(callid, rc);
     236}
     237
    104238
    105239static void callback_out(device_t *device,
     
    125259}
    126260
    127 void remote_usbhc_interrupt_out(device_t *device, void *iface,
    128             ipc_callid_t callid, ipc_call_t *call)
    129 {
    130         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     261/** Process an outgoing transfer (both OUT and SETUP).
     262 *
     263 * @param device Target device.
     264 * @param callid Initiating caller.
     265 * @param call Initiating call.
     266 * @param transfer_func Transfer function (might be NULL).
     267 */
     268static void remote_usbhc_out_transfer(device_t *device,
     269    ipc_callid_t callid, ipc_call_t *call,
     270    usbhc_iface_transfer_out_t transfer_func)
     271{
     272        if (!transfer_func) {
     273                ipc_answer_0(callid, ENOTSUP);
     274                return;
     275        }
    131276
    132277        size_t expected_len = IPC_GET_ARG3(*call);
     
    149294        }
    150295
    151         if (!usb_iface->interrupt_out) {
    152                 ipc_answer_0(callid, ENOTSUP);
    153                 return;
    154         }
    155 
    156296        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    157297        trans->caller = callid;
    158         trans->buffer = NULL;
    159         trans->size = 0;
    160 
    161         int rc = usb_iface->interrupt_out(device, target, buffer, len,
     298        trans->buffer = buffer;
     299        trans->size = len;
     300
     301        int rc = transfer_func(device, target, buffer, len,
    162302            callback_out, trans);
    163303
    164304        if (rc != EOK) {
    165305                ipc_answer_0(callid, rc);
     306                if (buffer != NULL) {
     307                        free(buffer);
     308                }
    166309                free(trans);
    167310        }
    168311}
    169312
    170 void remote_usbhc_interrupt_in(device_t *device, void *iface,
    171             ipc_callid_t callid, ipc_call_t *call)
    172 {
    173         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     313/** Process an incoming transfer.
     314 *
     315 * @param device Target device.
     316 * @param callid Initiating caller.
     317 * @param call Initiating call.
     318 * @param transfer_func Transfer function (might be NULL).
     319 */
     320static void remote_usbhc_in_transfer(device_t *device,
     321    ipc_callid_t callid, ipc_call_t *call,
     322    usbhc_iface_transfer_in_t transfer_func)
     323{
     324        if (!transfer_func) {
     325                ipc_answer_0(callid, ENOTSUP);
     326                return;
     327        }
    174328
    175329        size_t len = IPC_GET_ARG3(*call);
     
    179333        };
    180334
    181         if (!usb_iface->interrupt_in) {
    182                 ipc_answer_0(callid, ENOTSUP);
    183                 return;
    184         }
    185 
    186335        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    187336        trans->caller = callid;
     
    189338        trans->size = len;
    190339
    191         int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,
     340        int rc = transfer_func(device, target, trans->buffer, len,
    192341            callback_in, trans);
    193342
     
    199348}
    200349
     350/** Process status part of control transfer.
     351 *
     352 * @param device Target device.
     353 * @param callid Initiating caller.
     354 * @param call Initiating call.
     355 * @param direction Transfer direction (read ~ in, write ~ out).
     356 * @param transfer_in_func Transfer function for control read (might be NULL).
     357 * @param transfer_out_func Transfer function for control write (might be NULL).
     358 */
     359static void remote_usbhc_status_transfer(device_t *device,
     360    ipc_callid_t callid, ipc_call_t *call,
     361    usb_direction_t direction,
     362    int (*transfer_in_func)(device_t *, usb_target_t,
     363        usbhc_iface_transfer_in_callback_t, void *),
     364    int (*transfer_out_func)(device_t *, usb_target_t,
     365        usbhc_iface_transfer_out_callback_t, void *))
     366{
     367        switch (direction) {
     368                case USB_DIRECTION_IN:
     369                        if (!transfer_in_func) {
     370                                ipc_answer_0(callid, ENOTSUP);
     371                                return;
     372                        }
     373                        break;
     374                case USB_DIRECTION_OUT:
     375                        if (!transfer_out_func) {
     376                                ipc_answer_0(callid, ENOTSUP);
     377                                return;
     378                        }
     379                        break;
     380                default:
     381                        assert(false && "unreachable code");
     382                        break;
     383        }
     384
     385        usb_target_t target = {
     386                .address = IPC_GET_ARG1(*call),
     387                .endpoint = IPC_GET_ARG2(*call)
     388        };
     389
     390        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     391        trans->caller = callid;
     392        trans->buffer = NULL;
     393        trans->size = 0;
     394
     395        int rc;
     396        switch (direction) {
     397                case USB_DIRECTION_IN:
     398                        rc = transfer_in_func(device, target,
     399                            callback_in, trans);
     400                        break;
     401                case USB_DIRECTION_OUT:
     402                        rc = transfer_out_func(device, target,
     403                            callback_out, trans);
     404                        break;
     405                default:
     406                        assert(false && "unreachable code");
     407                        break;
     408        }
     409
     410        if (rc != EOK) {
     411                ipc_answer_0(callid, rc);
     412                free(trans);
     413        }
     414        return;
     415}
     416
     417
     418void remote_usbhc_interrupt_out(device_t *device, void *iface,
     419    ipc_callid_t callid, ipc_call_t *call)
     420{
     421        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     422        assert(usb_iface != NULL);
     423
     424        return remote_usbhc_out_transfer(device, callid, call,
     425            usb_iface->interrupt_out);
     426}
     427
     428void remote_usbhc_interrupt_in(device_t *device, void *iface,
     429    ipc_callid_t callid, ipc_call_t *call)
     430{
     431        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     432        assert(usb_iface != NULL);
     433
     434        return remote_usbhc_in_transfer(device, callid, call,
     435            usb_iface->interrupt_in);
     436}
     437
     438void remote_usbhc_control_write_setup(device_t *device, void *iface,
     439    ipc_callid_t callid, ipc_call_t *call)
     440{
     441        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     442        assert(usb_iface != NULL);
     443
     444        return remote_usbhc_out_transfer(device, callid, call,
     445            usb_iface->control_write_setup);
     446}
     447
     448void remote_usbhc_control_write_data(device_t *device, void *iface,
     449    ipc_callid_t callid, ipc_call_t *call)
     450{
     451        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     452        assert(usb_iface != NULL);
     453
     454        return remote_usbhc_out_transfer(device, callid, call,
     455            usb_iface->control_write_data);
     456}
     457
     458void remote_usbhc_control_write_status(device_t *device, void *iface,
     459    ipc_callid_t callid, ipc_call_t *call)
     460{
     461        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     462        assert(usb_iface != NULL);
     463
     464        return remote_usbhc_status_transfer(device, callid, call,
     465            USB_DIRECTION_IN, usb_iface->control_write_status, NULL);
     466}
     467
     468void remote_usbhc_control_read_setup(device_t *device, void *iface,
     469    ipc_callid_t callid, ipc_call_t *call)
     470{
     471        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     472        assert(usb_iface != NULL);
     473
     474        return remote_usbhc_out_transfer(device, callid, call,
     475            usb_iface->control_read_setup);
     476}
     477
     478void remote_usbhc_control_read_data(device_t *device, void *iface,
     479            ipc_callid_t callid, ipc_call_t *call)
     480{
     481        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     482        assert(usb_iface != NULL);
     483
     484        return remote_usbhc_in_transfer(device, callid, call,
     485            usb_iface->control_read_data);
     486}
     487
     488void remote_usbhc_control_read_status(device_t *device, void *iface,
     489            ipc_callid_t callid, ipc_call_t *call)
     490{
     491        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     492        assert(usb_iface != NULL);
     493
     494        return remote_usbhc_status_transfer(device, callid, call,
     495            USB_DIRECTION_OUT, NULL, usb_iface->control_read_status);
     496}
     497
     498
    201499
    202500/**
Note: See TracChangeset for help on using the changeset viewer.