Ignore:
File:
1 edited

Legend:

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

    r76daaf9f r357a302  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    3636#include <errno.h>
    3737#include <usb/usb.h>
    38 #include <usb/hcd.h>
     38#include <usb/addrkeep.h>
     39#include <usb/ddfiface.h>
    3940
    4041#include "vhcd.h"
    4142#include "conn.h"
    4243#include "hc.h"
     44
    4345
    4446typedef struct {
     
    4749        usbhc_iface_transfer_in_callback_t in_callback;
    4850        device_t *dev;
     51        size_t reported_size;
    4952        void *arg;
    5053} transfer_info_t;
    5154
     55typedef struct {
     56        usb_direction_t direction;
     57        usb_target_t target;
     58        usbhc_iface_transfer_out_callback_t out_callback;
     59        usbhc_iface_transfer_in_callback_t in_callback;
     60        device_t *dev;
     61        void *arg;
     62        void *data_buffer;
     63        size_t data_buffer_size;
     64} control_transfer_info_t;
     65
    5266static void universal_callback(void *buffer, size_t size,
    53     usb_transaction_outcome_t outcome, void *arg)
     67    int outcome, void *arg)
    5468{
    5569        transfer_info_t *transfer = (transfer_info_t *) arg;
     70
     71        if (transfer->reported_size != (size_t) -1) {
     72                size = transfer->reported_size;
     73        }
    5674
    5775        switch (transfer->direction) {
     
    84102        transfer->arg = arg;
    85103        transfer->dev = dev;
     104        transfer->reported_size = (size_t) -1;
     105
     106        return transfer;
     107}
     108
     109static void control_abort_prematurely(control_transfer_info_t *transfer,
     110    size_t size, int outcome)
     111{
     112        switch (transfer->direction) {
     113                case USB_DIRECTION_IN:
     114                        transfer->in_callback(transfer->dev,
     115                            outcome, size,
     116                            transfer->arg);
     117                        break;
     118                case USB_DIRECTION_OUT:
     119                        transfer->out_callback(transfer->dev,
     120                            outcome,
     121                            transfer->arg);
     122                        break;
     123                default:
     124                        assert(false && "unreachable");
     125                        break;
     126        }
     127}
     128
     129static void control_callback_two(void *buffer, size_t size,
     130    int outcome, void *arg)
     131{
     132        control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg;
     133
     134        if (outcome != EOK) {
     135                control_abort_prematurely(ctrl_transfer, outcome, size);
     136                free(ctrl_transfer);
     137                return;
     138        }
     139
     140        transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->dev,
     141            ctrl_transfer->direction, ctrl_transfer->arg);
     142        transfer->out_callback = ctrl_transfer->out_callback;
     143        transfer->in_callback = ctrl_transfer->in_callback;
     144        transfer->reported_size = size;
     145
     146        switch (ctrl_transfer->direction) {
     147                case USB_DIRECTION_IN:
     148                        hc_add_transaction_to_device(false, ctrl_transfer->target,
     149                            USB_TRANSFER_CONTROL,
     150                            NULL, 0,
     151                            universal_callback, transfer);
     152                        break;
     153                case USB_DIRECTION_OUT:
     154                        hc_add_transaction_from_device(ctrl_transfer->target,
     155                            USB_TRANSFER_CONTROL,
     156                            NULL, 0,
     157                            universal_callback, transfer);
     158                        break;
     159                default:
     160                        assert(false && "unreachable");
     161                        break;
     162        }
     163
     164        free(ctrl_transfer);
     165}
     166
     167static void control_callback_one(void *buffer, size_t size,
     168    int outcome, void *arg)
     169{
     170        control_transfer_info_t *transfer = (control_transfer_info_t *) arg;
     171
     172        if (outcome != EOK) {
     173                control_abort_prematurely(transfer, outcome, size);
     174                free(transfer);
     175                return;
     176        }
     177
     178        switch (transfer->direction) {
     179                case USB_DIRECTION_IN:
     180                        hc_add_transaction_from_device(transfer->target,
     181                            USB_TRANSFER_CONTROL,
     182                            transfer->data_buffer, transfer->data_buffer_size,
     183                            control_callback_two, transfer);
     184                        break;
     185                case USB_DIRECTION_OUT:
     186                        hc_add_transaction_to_device(false, transfer->target,
     187                            USB_TRANSFER_CONTROL,
     188                            transfer->data_buffer, transfer->data_buffer_size,
     189                            control_callback_two, transfer);
     190                        break;
     191                default:
     192                        assert(false && "unreachable");
     193                        break;
     194        }
     195}
     196
     197static control_transfer_info_t *create_control_transfer_info(device_t *dev,
     198    usb_direction_t direction, usb_target_t target,
     199    void *data_buffer, size_t data_buffer_size,
     200    void *arg)
     201{
     202        control_transfer_info_t *transfer
     203            = malloc(sizeof(control_transfer_info_t));
     204
     205        transfer->direction = direction;
     206        transfer->target = target;
     207        transfer->in_callback = NULL;
     208        transfer->out_callback = NULL;
     209        transfer->arg = arg;
     210        transfer->dev = dev;
     211        transfer->data_buffer = data_buffer;
     212        transfer->data_buffer_size = data_buffer_size;
    86213
    87214        return transfer;
     
    93220    usbhc_iface_transfer_out_callback_t callback, void *arg)
    94221{
    95         dprintf(3, "transfer OUT [%d.%d (%s); %zu]",
     222        usb_log_debug2("Transfer OUT [%d.%d (%s); %zu].\n",
    96223            target.address, target.endpoint,
    97224            usb_str_transfer_type(transfer_type),
     
    103230
    104231        hc_add_transaction_to_device(false, target, transfer_type, buffer, size,
    105             universal_callback, transfer);
    106 
    107         return EOK;
    108 }
    109 
    110 static int enqueue_transfer_setup(device_t *dev,
    111     usb_target_t target, usb_transfer_type_t transfer_type,
    112     void *buffer, size_t size,
    113     usbhc_iface_transfer_out_callback_t callback, void *arg)
    114 {
    115         dprintf(3, "transfer SETUP [%d.%d (%s); %zu]",
    116             target.address, target.endpoint,
    117             usb_str_transfer_type(transfer_type),
    118             size);
    119 
    120         transfer_info_t *transfer
    121             = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
    122         transfer->out_callback = callback;
    123 
    124         hc_add_transaction_to_device(true, target, transfer_type, buffer, size,
    125232            universal_callback, transfer);
    126233
     
    133240    usbhc_iface_transfer_in_callback_t callback, void *arg)
    134241{
    135         dprintf(3, "transfer IN [%d.%d (%s); %zu]",
     242        usb_log_debug2("Transfer IN [%d.%d (%s); %zu].\n",
    136243            target.address, target.endpoint,
    137244            usb_str_transfer_type(transfer_type),
     
    150257
    151258static int interrupt_out(device_t *dev, usb_target_t target,
     259    size_t max_packet_size,
    152260    void *data, size_t size,
    153261    usbhc_iface_transfer_out_callback_t callback, void *arg)
     
    159267
    160268static int interrupt_in(device_t *dev, usb_target_t target,
     269    size_t max_packet_size,
    161270    void *data, size_t size,
    162271    usbhc_iface_transfer_in_callback_t callback, void *arg)
     
    167276}
    168277
    169 static int control_write_setup(device_t *dev, usb_target_t target,
    170     void *data, size_t size,
     278static int control_write(device_t *dev, usb_target_t target,
     279    size_t max_packet_size,
     280    void *setup_packet, size_t setup_packet_size,
     281    void *data, size_t data_size,
    171282    usbhc_iface_transfer_out_callback_t callback, void *arg)
    172283{
    173         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    174             data, size,
    175             callback, arg);
    176 }
    177 
    178 static int control_write_data(device_t *dev, usb_target_t target,
    179     void *data, size_t size,
    180     usbhc_iface_transfer_out_callback_t callback, void *arg)
    181 {
    182         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    183             data, size,
    184             callback, arg);
    185 }
    186 
    187 static int control_write_status(device_t *dev, usb_target_t target,
     284        control_transfer_info_t *transfer
     285            = create_control_transfer_info(dev, USB_DIRECTION_OUT, target,
     286            data, data_size, arg);
     287        transfer->out_callback = callback;
     288
     289        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     290            setup_packet, setup_packet_size,
     291            control_callback_one, transfer);
     292
     293        return EOK;
     294}
     295
     296static int control_read(device_t *dev, usb_target_t target,
     297    size_t max_packet_size,
     298    void *setup_packet, size_t setup_packet_size,
     299    void *data, size_t data_size,
    188300    usbhc_iface_transfer_in_callback_t callback, void *arg)
    189301{
    190         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    191             NULL, 0,
    192             callback, arg);
    193 }
    194 
    195 static int control_read_setup(device_t *dev, usb_target_t target,
    196     void *data, size_t size,
    197     usbhc_iface_transfer_out_callback_t callback, void *arg)
    198 {
    199         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    200             data, size,
    201             callback, arg);
    202 }
    203 
    204 static int control_read_data(device_t *dev, usb_target_t target,
    205     void *data, size_t size,
    206     usbhc_iface_transfer_in_callback_t callback, void *arg)
    207 {
    208         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    209             data, size,
    210             callback, arg);
    211 }
    212 
    213 static int control_read_status(device_t *dev, usb_target_t target,
    214     usbhc_iface_transfer_out_callback_t callback, void *arg)
    215 {
    216         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    217             NULL, 0,
    218             callback, arg);
     302        control_transfer_info_t *transfer
     303            = create_control_transfer_info(dev, USB_DIRECTION_IN, target,
     304            data, data_size, arg);
     305        transfer->in_callback = callback;
     306
     307        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     308            setup_packet, setup_packet_size,
     309            control_callback_one, transfer);
     310
     311        return EOK;
    219312}
    220313
    221314static usb_address_keeping_t addresses;
    222315
    223 
    224 static int reserve_default_address(device_t *dev)
     316static int tell_address(device_t *dev, devman_handle_t handle,
     317    usb_address_t *address)
     318{
     319        usb_address_t addr = usb_address_keeping_find(&addresses, handle);
     320        if (addr < 0) {
     321                return addr;
     322        }
     323
     324        *address = addr;
     325        return EOK;
     326}
     327
     328static int reserve_default_address(device_t *dev, usb_speed_t ignored)
    225329{
    226330        usb_address_keeping_reserve_default(&addresses);
     
    234338}
    235339
    236 static int request_address(device_t *dev, usb_address_t *address)
     340static int request_address(device_t *dev, usb_speed_t ignored,
     341    usb_address_t *address)
    237342{
    238343        usb_address_t addr = usb_address_keeping_request(&addresses);
     
    257362}
    258363
    259 static int tell_address(device_t *dev, devman_handle_t handle,
    260     usb_address_t *address)
    261 {
    262         usb_address_t addr = usb_address_keeping_find(&addresses, handle);
    263         if (addr < 0) {
    264                 return addr;
    265         }
    266 
    267         *address = addr;
    268         return EOK;
    269 }
    270 
    271364void address_init(void)
    272365{
     
    275368
    276369usbhc_iface_t vhc_iface = {
    277         .tell_address = tell_address,
    278 
    279370        .reserve_default_address = reserve_default_address,
    280371        .release_default_address = release_default_address,
     
    286377        .interrupt_in = interrupt_in,
    287378
    288         .control_write_setup = control_write_setup,
    289         .control_write_data = control_write_data,
    290         .control_write_status = control_write_status,
    291 
    292         .control_read_setup = control_read_setup,
    293         .control_read_data = control_read_data,
    294         .control_read_status = control_read_status
     379        .control_write = control_write,
     380        .control_read = control_read
    295381};
     382
     383usb_iface_t vhc_usb_iface = {
     384        .get_hc_handle = usb_iface_get_hc_handle_hc_impl,
     385        .get_address = tell_address
     386};
     387
    296388
    297389/**
Note: See TracChangeset for help on using the changeset viewer.