Changeset fb1dca09 in mainline


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

Refactoring of remote USBHC interface

It is still not optimal but at least less error prone.

Location:
uspace/lib/drv
Files:
2 edited

Legend:

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

    r710f518 rfb1dca09  
    159159}
    160160
    161 void remote_usbhc_interrupt_out(device_t *device, void *iface,
    162             ipc_callid_t callid, ipc_call_t *call)
    163 {
    164         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        }
    165176
    166177        size_t expected_len = IPC_GET_ARG3(*call);
     
    183194        }
    184195
    185         if (!usb_iface->interrupt_out) {
    186                 ipc_answer_0(callid, ENOTSUP);
    187                 return;
    188         }
    189 
    190196        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    191197        trans->caller = callid;
    192         trans->buffer = NULL;
    193         trans->size = 0;
    194 
    195         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,
    196202            callback_out, trans);
    197203
    198204        if (rc != EOK) {
    199205                ipc_answer_0(callid, rc);
     206                if (buffer != NULL) {
     207                        free(buffer);
     208                }
    200209                free(trans);
    201210        }
    202211}
    203212
    204 void remote_usbhc_interrupt_in(device_t *device, void *iface,
    205             ipc_callid_t callid, ipc_call_t *call)
    206 {
    207         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        }
    208228
    209229        size_t len = IPC_GET_ARG3(*call);
     
    213233        };
    214234
    215         if (!usb_iface->interrupt_in) {
    216                 ipc_answer_0(callid, ENOTSUP);
    217                 return;
    218         }
    219 
    220235        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    221236        trans->caller = callid;
     
    223238        trans->size = len;
    224239
    225         int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,
     240        int rc = transfer_func(device, target, trans->buffer, len,
    226241            callback_in, trans);
    227242
     
    233248}
    234249
    235 void 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);
     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
    241285        usb_target_t target = {
    242286                .address = IPC_GET_ARG1(*call),
     
    244288        };
    245289
    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 
    264290        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    265291        trans->caller = callid;
     
    267293        trans->size = 0;
    268294
    269         int rc = usb_iface->control_write_setup(device, target, buffer, len,
    270             callback_out, trans);
     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        }
    271309
    272310        if (rc != EOK) {
     
    274312                free(trans);
    275313        }
     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);
    276346}
    277347
    278348void 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         }
     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);
    319356}
    320357
    321358void 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         }
     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);
    348366}
    349367
    350368void 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         }
     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);
    391376}
    392377
     
    395380{
    396381        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         }
     382        assert(usb_iface != NULL);
     383
     384        return remote_usbhc_in_transfer(device, callid, call,
     385            usb_iface->control_read_data);
    422386}
    423387
     
    426390{
    427391        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         }
     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);
    451396}
    452397
  • uspace/lib/drv/include/usbhc_iface.h

    r710f518 rfb1dca09  
    166166    usb_transaction_outcome_t, size_t, void *);
    167167
     168
     169/** Out transfer processing function prototype. */
     170typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t,
     171    void *, size_t,
     172    usbhc_iface_transfer_out_callback_t, void *);
     173
     174/** Setup transfer processing function prototype. */
     175typedef usbhc_iface_transfer_out_t usbhc_iface_transfer_setup_t;
     176
     177/** In transfer processing function prototype. */
     178typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t,
     179    void *, size_t,
     180    usbhc_iface_transfer_in_callback_t, void *);
     181
    168182/** USB devices communication interface. */
    169183typedef struct {
    170184        int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
    171185
    172         int (*interrupt_out)(device_t *, usb_target_t,
    173             void *, size_t,
    174             usbhc_iface_transfer_out_callback_t, void *);
    175         int (*interrupt_in)(device_t *, usb_target_t,
    176             void *, size_t,
    177             usbhc_iface_transfer_in_callback_t, void *);
    178 
    179         int (*control_write_setup)(device_t *, usb_target_t,
    180             void *, size_t,
    181             usbhc_iface_transfer_out_callback_t, void *);
    182         int (*control_write_data)(device_t *, usb_target_t,
    183             void *, size_t,
    184             usbhc_iface_transfer_out_callback_t, void *);
     186        usbhc_iface_transfer_out_t interrupt_out;
     187        usbhc_iface_transfer_in_t interrupt_in;
     188
     189        usbhc_iface_transfer_setup_t control_write_setup;
     190        usbhc_iface_transfer_out_t control_write_data;
    185191        int (*control_write_status)(device_t *, usb_target_t,
    186192            usbhc_iface_transfer_in_callback_t, void *);
    187193
    188         int (*control_read_setup)(device_t *, usb_target_t,
    189             void *, size_t,
    190             usbhc_iface_transfer_out_callback_t, void *);
    191         int (*control_read_data)(device_t *, usb_target_t,
    192             void *, size_t,
    193             usbhc_iface_transfer_in_callback_t, void *);
     194        usbhc_iface_transfer_setup_t control_read_setup;
     195        usbhc_iface_transfer_in_t control_read_data;
    194196        int (*control_read_status)(device_t *, usb_target_t,
    195197            usbhc_iface_transfer_out_callback_t, void *);
Note: See TracChangeset for help on using the changeset viewer.