Changeset 284c629 in mainline


Ignore:
Timestamp:
2011-02-01T21:01:39Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0a37e14
Parents:
33b88723
Message:

Virtual HC handles atomic control transfers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/vhc/connhost.c

    r33b88723 r284c629  
    4242#include "hc.h"
    4343
     44
    4445typedef struct {
    4546        usb_direction_t direction;
     
    4748        usbhc_iface_transfer_in_callback_t in_callback;
    4849        device_t *dev;
     50        size_t reported_size;
    4951        void *arg;
    5052} transfer_info_t;
    5153
     54typedef struct {
     55        usb_direction_t direction;
     56        usb_target_t target;
     57        usbhc_iface_transfer_out_callback_t out_callback;
     58        usbhc_iface_transfer_in_callback_t in_callback;
     59        device_t *dev;
     60        void *arg;
     61        void *data_buffer;
     62        size_t data_buffer_size;
     63} control_transfer_info_t;
     64
    5265static void universal_callback(void *buffer, size_t size,
    5366    usb_transaction_outcome_t outcome, void *arg)
    5467{
    5568        transfer_info_t *transfer = (transfer_info_t *) arg;
     69
     70        if (transfer->reported_size != (size_t) -1) {
     71                size = transfer->reported_size;
     72        }
    5673
    5774        switch (transfer->direction) {
     
    84101        transfer->arg = arg;
    85102        transfer->dev = dev;
     103        transfer->reported_size = (size_t) -1;
     104
     105        return transfer;
     106}
     107
     108static void control_abort_prematurely(control_transfer_info_t *transfer,
     109    size_t size, usb_transaction_outcome_t outcome)
     110{
     111        switch (transfer->direction) {
     112                case USB_DIRECTION_IN:
     113                        transfer->in_callback(transfer->dev,
     114                            outcome, size,
     115                            transfer->arg);
     116                        break;
     117                case USB_DIRECTION_OUT:
     118                        transfer->out_callback(transfer->dev,
     119                            outcome,
     120                            transfer->arg);
     121                        break;
     122                default:
     123                        assert(false && "unreachable");
     124                        break;
     125        }
     126}
     127
     128static void control_callback_two(void *buffer, size_t size,
     129    usb_transaction_outcome_t outcome, void *arg)
     130{
     131        control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg;
     132
     133        if (outcome != USB_OUTCOME_OK) {
     134                control_abort_prematurely(ctrl_transfer, outcome, size);
     135                free(ctrl_transfer);
     136                return;
     137        }
     138
     139        transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->dev,
     140            ctrl_transfer->direction, ctrl_transfer->arg);
     141        transfer->out_callback = ctrl_transfer->out_callback;
     142        transfer->in_callback = ctrl_transfer->in_callback;
     143        transfer->reported_size = size;
     144
     145        switch (ctrl_transfer->direction) {
     146                case USB_DIRECTION_IN:
     147                        hc_add_transaction_to_device(false, ctrl_transfer->target,
     148                            USB_TRANSFER_CONTROL,
     149                            NULL, 0,
     150                            universal_callback, transfer);
     151                        break;
     152                case USB_DIRECTION_OUT:
     153                        hc_add_transaction_from_device(ctrl_transfer->target,
     154                            USB_TRANSFER_CONTROL,
     155                            NULL, 0,
     156                            universal_callback, transfer);
     157                        break;
     158                default:
     159                        assert(false && "unreachable");
     160                        break;
     161        }
     162
     163        free(ctrl_transfer);
     164}
     165
     166static void control_callback_one(void *buffer, size_t size,
     167    usb_transaction_outcome_t outcome, void *arg)
     168{
     169        control_transfer_info_t *transfer = (control_transfer_info_t *) arg;
     170
     171        if (outcome != USB_OUTCOME_OK) {
     172                control_abort_prematurely(transfer, outcome, size);
     173                free(transfer);
     174                return;
     175        }
     176
     177        switch (transfer->direction) {
     178                case USB_DIRECTION_IN:
     179                        hc_add_transaction_from_device(transfer->target,
     180                            USB_TRANSFER_CONTROL,
     181                            transfer->data_buffer, transfer->data_buffer_size,
     182                            control_callback_two, transfer);
     183                        break;
     184                case USB_DIRECTION_OUT:
     185                        hc_add_transaction_to_device(false, transfer->target,
     186                            USB_TRANSFER_CONTROL,
     187                            transfer->data_buffer, transfer->data_buffer_size,
     188                            control_callback_two, transfer);
     189                        break;
     190                default:
     191                        assert(false && "unreachable");
     192                        break;
     193        }
     194}
     195
     196static control_transfer_info_t *create_control_transfer_info(device_t *dev,
     197    usb_direction_t direction, usb_target_t target,
     198    void *data_buffer, size_t data_buffer_size,
     199    void *arg)
     200{
     201        control_transfer_info_t *transfer
     202            = malloc(sizeof(control_transfer_info_t));
     203
     204        transfer->direction = direction;
     205        transfer->target = target;
     206        transfer->in_callback = NULL;
     207        transfer->out_callback = NULL;
     208        transfer->arg = arg;
     209        transfer->dev = dev;
     210        transfer->data_buffer = data_buffer;
     211        transfer->data_buffer_size = data_buffer_size;
    86212
    87213        return transfer;
     
    193319}
    194320
     321static int control_write(device_t *dev, usb_target_t target,
     322    void *setup_packet, size_t setup_packet_size,
     323    void *data, size_t data_size,
     324    usbhc_iface_transfer_out_callback_t callback, void *arg)
     325{
     326        control_transfer_info_t *transfer
     327            = create_control_transfer_info(dev, USB_DIRECTION_OUT, target,
     328            data, data_size, arg);
     329        transfer->out_callback = callback;
     330
     331        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     332            setup_packet, setup_packet_size,
     333            control_callback_one, transfer);
     334
     335        return EOK;
     336}
     337
    195338static int control_read_setup(device_t *dev, usb_target_t target,
    196339    void *data, size_t size,
     
    217360            NULL, 0,
    218361            callback, arg);
     362}
     363
     364static int control_read(device_t *dev, usb_target_t target,
     365    void *setup_packet, size_t setup_packet_size,
     366    void *data, size_t data_size,
     367    usbhc_iface_transfer_in_callback_t callback, void *arg)
     368{
     369        control_transfer_info_t *transfer
     370            = create_control_transfer_info(dev, USB_DIRECTION_IN, target,
     371            data, data_size, arg);
     372        transfer->in_callback = callback;
     373
     374        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     375            setup_packet, setup_packet_size,
     376            control_callback_one, transfer);
     377
     378        return EOK;
    219379}
    220380
     
    290450        .control_write_status = control_write_status,
    291451
     452        .control_write = control_write,
     453
    292454        .control_read_setup = control_read_setup,
    293455        .control_read_data = control_read_data,
    294         .control_read_status = control_read_status
     456        .control_read_status = control_read_status,
     457
     458        .control_read = control_read
    295459};
    296460
Note: See TracChangeset for help on using the changeset viewer.