Ignore:
Timestamp:
2010-12-03T13:03:26Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
101ef25c
Parents:
bbc28be (diff), 4570779 (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 branch development into lelian/hidd

File:
1 edited

Legend:

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

    rbbc28be r70c85211  
    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 *);
     54//static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4855
    4956/** Remote USB interface operations. */
    5057static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
    51         &remote_usbhc_get_buffer,
    52         &remote_usbhc_interrupt_out,
    53         &remote_usbhc_interrupt_in
     58        remote_usbhc_get_address,
     59        remote_usbhc_get_buffer,
     60        remote_usbhc_interrupt_out,
     61        remote_usbhc_interrupt_in,
     62        remote_usbhc_control_write_setup,
     63        remote_usbhc_control_write_data,
     64        remote_usbhc_control_write_status,
     65        remote_usbhc_control_read_setup,
     66        remote_usbhc_control_read_data,
     67        remote_usbhc_control_read_status
    5468};
    5569
     
    6882} async_transaction_t;
    6983
     84void remote_usbhc_get_address(device_t *device, void *iface,
     85    ipc_callid_t callid, ipc_call_t *call)
     86{
     87        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     88
     89        if (!usb_iface->tell_address) {
     90                ipc_answer_0(callid, ENOTSUP);
     91                return;
     92        }
     93
     94        devman_handle_t handle = IPC_GET_ARG1(*call);
     95
     96        usb_address_t address;
     97        int rc = usb_iface->tell_address(device, handle, &address);
     98        if (rc != EOK) {
     99                ipc_answer_0(callid, rc);
     100        } else {
     101                ipc_answer_1(callid, EOK, address);
     102        }
     103}
    70104
    71105void remote_usbhc_get_buffer(device_t *device, void *iface,
     
    125159}
    126160
    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;
     161/** Process an outgoing transfer (both OUT and SETUP).
     162 *
     163 * @param device Target device.
     164 * @param callid Initiating caller.
     165 * @param call Initiating call.
     166 * @param transfer_func Transfer function (might be NULL).
     167 */
     168static void remote_usbhc_out_transfer(device_t *device,
     169    ipc_callid_t callid, ipc_call_t *call,
     170    usbhc_iface_transfer_out_t transfer_func)
     171{
     172        if (!transfer_func) {
     173                ipc_answer_0(callid, ENOTSUP);
     174                return;
     175        }
    131176
    132177        size_t expected_len = IPC_GET_ARG3(*call);
     
    149194        }
    150195
    151         if (!usb_iface->interrupt_out) {
    152                 ipc_answer_0(callid, ENOTSUP);
    153                 return;
    154         }
    155 
    156196        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    157197        trans->caller = callid;
    158         trans->buffer = NULL;
    159         trans->size = 0;
    160 
    161         int rc = usb_iface->interrupt_out(device, target, buffer, len,
     198        trans->buffer = buffer;
     199        trans->size = len;
     200
     201        int rc = transfer_func(device, target, buffer, len,
    162202            callback_out, trans);
    163203
    164204        if (rc != EOK) {
    165205                ipc_answer_0(callid, rc);
     206                if (buffer != NULL) {
     207                        free(buffer);
     208                }
    166209                free(trans);
    167210        }
    168211}
    169212
    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;
     213/** Process an incoming transfer.
     214 *
     215 * @param device Target device.
     216 * @param callid Initiating caller.
     217 * @param call Initiating call.
     218 * @param transfer_func Transfer function (might be NULL).
     219 */
     220static void remote_usbhc_in_transfer(device_t *device,
     221    ipc_callid_t callid, ipc_call_t *call,
     222    usbhc_iface_transfer_in_t transfer_func)
     223{
     224        if (!transfer_func) {
     225                ipc_answer_0(callid, ENOTSUP);
     226                return;
     227        }
    174228
    175229        size_t len = IPC_GET_ARG3(*call);
     
    179233        };
    180234
    181         if (!usb_iface->interrupt_in) {
    182                 ipc_answer_0(callid, ENOTSUP);
    183                 return;
    184         }
    185 
    186235        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    187236        trans->caller = callid;
     
    189238        trans->size = len;
    190239
    191         int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,
     240        int rc = transfer_func(device, target, trans->buffer, len,
    192241            callback_in, trans);
    193242
     
    199248}
    200249
     250/** Process status part of control transfer.
     251 *
     252 * @param device Target device.
     253 * @param callid Initiating caller.
     254 * @param call Initiating call.
     255 * @param direction Transfer direction (read ~ in, write ~ out).
     256 * @param transfer_in_func Transfer function for control read (might be NULL).
     257 * @param transfer_out_func Transfer function for control write (might be NULL).
     258 */
     259static void remote_usbhc_status_transfer(device_t *device,
     260    ipc_callid_t callid, ipc_call_t *call,
     261    usb_direction_t direction,
     262    int (*transfer_in_func)(device_t *, usb_target_t,
     263        usbhc_iface_transfer_in_callback_t, void *),
     264    int (*transfer_out_func)(device_t *, usb_target_t,
     265        usbhc_iface_transfer_out_callback_t, void *))
     266{
     267        switch (direction) {
     268                case USB_DIRECTION_IN:
     269                        if (!transfer_in_func) {
     270                                ipc_answer_0(callid, ENOTSUP);
     271                                return;
     272                        }
     273                        break;
     274                case USB_DIRECTION_OUT:
     275                        if (!transfer_out_func) {
     276                                ipc_answer_0(callid, ENOTSUP);
     277                                return;
     278                        }
     279                        break;
     280                default:
     281                        assert(false && "unreachable code");
     282                        break;
     283        }
     284
     285        usb_target_t target = {
     286                .address = IPC_GET_ARG1(*call),
     287                .endpoint = IPC_GET_ARG2(*call)
     288        };
     289
     290        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     291        trans->caller = callid;
     292        trans->buffer = NULL;
     293        trans->size = 0;
     294
     295        int rc;
     296        switch (direction) {
     297                case USB_DIRECTION_IN:
     298                        rc = transfer_in_func(device, target,
     299                            callback_in, trans);
     300                        break;
     301                case USB_DIRECTION_OUT:
     302                        rc = transfer_out_func(device, target,
     303                            callback_out, trans);
     304                        break;
     305                default:
     306                        assert(false && "unreachable code");
     307                        break;
     308        }
     309
     310        if (rc != EOK) {
     311                ipc_answer_0(callid, rc);
     312                free(trans);
     313        }
     314        return;
     315}
     316
     317
     318void remote_usbhc_interrupt_out(device_t *device, void *iface,
     319    ipc_callid_t callid, ipc_call_t *call)
     320{
     321        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     322        assert(usb_iface != NULL);
     323
     324        return remote_usbhc_out_transfer(device, callid, call,
     325            usb_iface->interrupt_out);
     326}
     327
     328void remote_usbhc_interrupt_in(device_t *device, void *iface,
     329    ipc_callid_t callid, ipc_call_t *call)
     330{
     331        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     332        assert(usb_iface != NULL);
     333
     334        return remote_usbhc_in_transfer(device, callid, call,
     335            usb_iface->interrupt_in);
     336}
     337
     338void remote_usbhc_control_write_setup(device_t *device, void *iface,
     339    ipc_callid_t callid, ipc_call_t *call)
     340{
     341        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     342        assert(usb_iface != NULL);
     343
     344        return remote_usbhc_out_transfer(device, callid, call,
     345            usb_iface->control_write_setup);
     346}
     347
     348void remote_usbhc_control_write_data(device_t *device, void *iface,
     349    ipc_callid_t callid, ipc_call_t *call)
     350{
     351        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     352        assert(usb_iface != NULL);
     353
     354        return remote_usbhc_out_transfer(device, callid, call,
     355            usb_iface->control_write_data);
     356}
     357
     358void remote_usbhc_control_write_status(device_t *device, void *iface,
     359    ipc_callid_t callid, ipc_call_t *call)
     360{
     361        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     362        assert(usb_iface != NULL);
     363
     364        return remote_usbhc_status_transfer(device, callid, call,
     365            USB_DIRECTION_IN, usb_iface->control_write_status, NULL);
     366}
     367
     368void remote_usbhc_control_read_setup(device_t *device, void *iface,
     369    ipc_callid_t callid, ipc_call_t *call)
     370{
     371        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     372        assert(usb_iface != NULL);
     373
     374        return remote_usbhc_out_transfer(device, callid, call,
     375            usb_iface->control_read_setup);
     376}
     377
     378void remote_usbhc_control_read_data(device_t *device, void *iface,
     379            ipc_callid_t callid, ipc_call_t *call)
     380{
     381        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     382        assert(usb_iface != NULL);
     383
     384        return remote_usbhc_in_transfer(device, callid, call,
     385            usb_iface->control_read_data);
     386}
     387
     388void remote_usbhc_control_read_status(device_t *device, void *iface,
     389            ipc_callid_t callid, ipc_call_t *call)
     390{
     391        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     392        assert(usb_iface != NULL);
     393
     394        return remote_usbhc_status_transfer(device, callid, call,
     395            USB_DIRECTION_OUT, NULL, usb_iface->control_read_status);
     396}
     397
     398
    201399
    202400/**
Note: See TracChangeset for help on using the changeset viewer.