Changeset 1b22bd4 in mainline for uspace/lib/drv/generic/remote_usb.c


Ignore:
Timestamp:
2010-11-20T14:48:18Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
32eceb4f
Parents:
4b4c797
Message:

Add remote USB interface implementation

Not tested, may be bugged ;-).

File:
1 edited

Legend:

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

    r4b4c797 r1b22bd4  
    4040#include "driver.h"
    4141
     42#define USB_MAX_PAYLOAD_SIZE 1020
     43
    4244static void remote_usb_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4345static void remote_usb_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    6062};
    6163
     64typedef struct {
     65        ipc_callid_t caller;
     66        void *buffer;
     67        size_t size;
     68} async_transaction_t;
    6269
    6370
     
    6572    ipc_callid_t callid, ipc_call_t *call)
    6673{
    67         ipc_answer_0(callid, ENOTSUP);
     74        ipcarg_t buffer_hash = IPC_GET_ARG1(*call);
     75        async_transaction_t * trans = (async_transaction_t *)buffer_hash;
     76        if (trans == NULL) {
     77                ipc_answer_0(callid, ENOENT);
     78                return;
     79        }
     80        if (trans->buffer == NULL) {
     81                ipc_answer_0(callid, EINVAL);
     82                free(trans);
     83                return;
     84        }
     85
     86        ipc_callid_t cid;
     87        size_t accepted_size;
     88        if (!async_data_read_receive(&cid, &accepted_size)) {
     89                ipc_answer_0(callid, EINVAL);
     90                return;
     91        }
     92
     93        if (accepted_size > trans->size) {
     94                accepted_size = trans->size;
     95        }
     96        async_data_read_finalize(callid, trans->buffer, accepted_size);
     97
     98        ipc_answer_1(callid, EOK, accepted_size);
     99
     100        free(trans->buffer);
     101        free(trans);
     102}
     103
     104
     105static void callback_out(device_t *device,
     106    usb_transaction_outcome_t outcome, void *arg)
     107{
     108        async_transaction_t *trans = (async_transaction_t *)arg;
     109
     110        // FIXME - answer according to outcome
     111        ipc_answer_0(trans->caller, EOK);
     112
     113        free(trans);
     114}
     115
     116static void callback_in(device_t *device,
     117    usb_transaction_outcome_t outcome, size_t actual_size, void *arg)
     118{
     119        async_transaction_t *trans = (async_transaction_t *)arg;
     120
     121        // FIXME - answer according to outcome
     122        ipc_answer_1(trans->caller, EOK, (ipcarg_t)trans);
     123
     124        trans->size = actual_size;
    68125}
    69126
     
    71128            ipc_callid_t callid, ipc_call_t *call)
    72129{
    73         ipc_answer_0(callid, ENOTSUP);
     130        usb_iface_t *usb_iface = (usb_iface_t *) iface;
     131
     132        size_t expected_len = IPC_GET_ARG3(*call);
     133        usb_target_t target = {
     134                .address = IPC_GET_ARG1(*call),
     135                .endpoint = IPC_GET_ARG2(*call)
     136        };
     137
     138        size_t len = 0;
     139        void *buffer = NULL;
     140        if (expected_len > 0) {
     141                int rc = async_data_write_accept(&buffer, false,
     142                    1, USB_MAX_PAYLOAD_SIZE,
     143                    0, &len);
     144
     145                if (rc != EOK) {
     146                        ipc_answer_0(callid, rc);
     147                        return;
     148                }
     149        }
     150
     151        if (!usb_iface->interrupt_out) {
     152                ipc_answer_0(callid, ENOTSUP);
     153                return;
     154        }
     155
     156        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     157        trans->caller = callid;
     158        trans->buffer = NULL;
     159        trans->size = 0;
     160
     161        int rc = usb_iface->interrupt_out(device, target, buffer, len,
     162            callback_out, trans);
     163
     164        if (rc != EOK) {
     165                ipc_answer_0(callid, rc);
     166                free(trans);
     167        }
    74168}
    75169
     
    77171            ipc_callid_t callid, ipc_call_t *call)
    78172{
    79         ipc_answer_0(callid, ENOTSUP);
    80 }
     173        usb_iface_t *usb_iface = (usb_iface_t *) iface;
     174
     175        size_t len = IPC_GET_ARG3(*call);
     176        usb_target_t target = {
     177                .address = IPC_GET_ARG1(*call),
     178                .endpoint = IPC_GET_ARG2(*call)
     179        };
     180
     181        if (!usb_iface->interrupt_in) {
     182                ipc_answer_0(callid, ENOTSUP);
     183                return;
     184        }
     185
     186        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     187        trans->caller = callid;
     188        trans->buffer = malloc(len);
     189        trans->size = len;
     190
     191        int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,
     192            callback_in, trans);
     193
     194        if (rc != EOK) {
     195                ipc_answer_0(callid, rc);
     196                free(trans->buffer);
     197                free(trans);
     198        }
     199}
     200
    81201
    82202/**
Note: See TracChangeset for help on using the changeset viewer.