Ignore:
Timestamp:
2010-11-28T17:30:54Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
710f518
Parents:
6c8ada21
Message:

Add control transfer to USBHC interface

The USBHC interface (of DDF) knows how to handle control transfers
(both read and write).

File:
1 edited

Legend:

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

    r6c8ada21 ra3dfb2e  
    4646static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4747static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
    48 //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 *);
    4955
    5056/** Remote USB interface operations. */
     
    5359        remote_usbhc_get_buffer,
    5460        remote_usbhc_interrupt_out,
    55         remote_usbhc_interrupt_in
     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
    5668};
    5769
     
    221233}
    222234
     235void remote_usbhc_control_write_setup(device_t *device, void *iface,
     236            ipc_callid_t callid, ipc_call_t *call)
     237{
     238        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     239
     240        size_t expected_len = IPC_GET_ARG3(*call);
     241        usb_target_t target = {
     242                .address = IPC_GET_ARG1(*call),
     243                .endpoint = IPC_GET_ARG2(*call)
     244        };
     245
     246        size_t len = 0;
     247        void *buffer = NULL;
     248        if (expected_len > 0) {
     249                int rc = async_data_write_accept(&buffer, false,
     250                    1, USB_MAX_PAYLOAD_SIZE,
     251                    0, &len);
     252
     253                if (rc != EOK) {
     254                        ipc_answer_0(callid, rc);
     255                        return;
     256                }
     257        }
     258
     259        if (!usb_iface->control_write_setup) {
     260                ipc_answer_0(callid, ENOTSUP);
     261                return;
     262        }
     263
     264        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     265        trans->caller = callid;
     266        trans->buffer = NULL;
     267        trans->size = 0;
     268
     269        int rc = usb_iface->control_write_setup(device, target, buffer, len,
     270            callback_out, trans);
     271
     272        if (rc != EOK) {
     273                ipc_answer_0(callid, rc);
     274                free(trans);
     275        }
     276}
     277
     278void remote_usbhc_control_write_data(device_t *device, void *iface,
     279            ipc_callid_t callid, ipc_call_t *call)
     280{
     281        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     282
     283        size_t expected_len = IPC_GET_ARG3(*call);
     284        usb_target_t target = {
     285                .address = IPC_GET_ARG1(*call),
     286                .endpoint = IPC_GET_ARG2(*call)
     287        };
     288
     289        size_t len = 0;
     290        void *buffer = NULL;
     291        if (expected_len > 0) {
     292                int rc = async_data_write_accept(&buffer, false,
     293                    1, USB_MAX_PAYLOAD_SIZE,
     294                    0, &len);
     295
     296                if (rc != EOK) {
     297                        ipc_answer_0(callid, rc);
     298                        return;
     299                }
     300        }
     301
     302        if (!usb_iface->control_write_data) {
     303                ipc_answer_0(callid, ENOTSUP);
     304                return;
     305        }
     306
     307        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     308        trans->caller = callid;
     309        trans->buffer = NULL;
     310        trans->size = 0;
     311
     312        int rc = usb_iface->control_write_data(device, target, buffer, len,
     313            callback_out, trans);
     314
     315        if (rc != EOK) {
     316                ipc_answer_0(callid, rc);
     317                free(trans);
     318        }
     319}
     320
     321void remote_usbhc_control_write_status(device_t *device, void *iface,
     322            ipc_callid_t callid, ipc_call_t *call)
     323{
     324        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     325
     326        usb_target_t target = {
     327                .address = IPC_GET_ARG1(*call),
     328                .endpoint = IPC_GET_ARG2(*call)
     329        };
     330
     331        if (!usb_iface->control_write_status) {
     332                ipc_answer_0(callid, ENOTSUP);
     333                return;
     334        }
     335
     336        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     337        trans->caller = callid;
     338        trans->buffer = NULL;
     339        trans->size = 0;
     340
     341        int rc = usb_iface->control_write_status(device, target,
     342            callback_in, trans);
     343
     344        if (rc != EOK) {
     345                ipc_answer_0(callid, rc);
     346                free(trans);
     347        }
     348}
     349
     350void remote_usbhc_control_read_setup(device_t *device, void *iface,
     351            ipc_callid_t callid, ipc_call_t *call)
     352{
     353        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     354
     355        size_t expected_len = IPC_GET_ARG3(*call);
     356        usb_target_t target = {
     357                .address = IPC_GET_ARG1(*call),
     358                .endpoint = IPC_GET_ARG2(*call)
     359        };
     360
     361        size_t len = 0;
     362        void *buffer = NULL;
     363        if (expected_len > 0) {
     364                int rc = async_data_write_accept(&buffer, false,
     365                    1, USB_MAX_PAYLOAD_SIZE,
     366                    0, &len);
     367
     368                if (rc != EOK) {
     369                        ipc_answer_0(callid, rc);
     370                        return;
     371                }
     372        }
     373
     374        if (!usb_iface->control_read_setup) {
     375                ipc_answer_0(callid, ENOTSUP);
     376                return;
     377        }
     378
     379        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     380        trans->caller = callid;
     381        trans->buffer = NULL;
     382        trans->size = 0;
     383
     384        int rc = usb_iface->control_read_setup(device, target, buffer, len,
     385            callback_out, trans);
     386
     387        if (rc != EOK) {
     388                ipc_answer_0(callid, rc);
     389                free(trans);
     390        }
     391}
     392
     393void remote_usbhc_control_read_data(device_t *device, void *iface,
     394            ipc_callid_t callid, ipc_call_t *call)
     395{
     396        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     397
     398        size_t len = IPC_GET_ARG3(*call);
     399        usb_target_t target = {
     400                .address = IPC_GET_ARG1(*call),
     401                .endpoint = IPC_GET_ARG2(*call)
     402        };
     403
     404        if (!usb_iface->control_read_data) {
     405                ipc_answer_0(callid, ENOTSUP);
     406                return;
     407        }
     408
     409        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     410        trans->caller = callid;
     411        trans->buffer = malloc(len);
     412        trans->size = len;
     413
     414        int rc = usb_iface->control_read_data(device, target, trans->buffer, len,
     415            callback_in, trans);
     416
     417        if (rc != EOK) {
     418                ipc_answer_0(callid, rc);
     419                free(trans->buffer);
     420                free(trans);
     421        }
     422}
     423
     424void remote_usbhc_control_read_status(device_t *device, void *iface,
     425            ipc_callid_t callid, ipc_call_t *call)
     426{
     427        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     428
     429        usb_target_t target = {
     430                .address = IPC_GET_ARG1(*call),
     431                .endpoint = IPC_GET_ARG2(*call)
     432        };
     433
     434        if (!usb_iface->control_read_status) {
     435                ipc_answer_0(callid, ENOTSUP);
     436                return;
     437        }
     438
     439        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     440        trans->caller = callid;
     441        trans->buffer = NULL;
     442        trans->size = 0;
     443
     444        int rc = usb_iface->control_read_status(device, target,
     445            callback_out, trans);
     446
     447        if (rc != EOK) {
     448                ipc_answer_0(callid, rc);
     449                free(trans);
     450        }
     451}
     452
     453
    223454
    224455/**
Note: See TracChangeset for help on using the changeset viewer.