Changeset b4b534ac in mainline for uspace/drv/bus/usb/vhc


Ignore:
Timestamp:
2016-07-22T08:24:47Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f76d2c2
Parents:
5b18137 (diff), 8351f9a4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jan.vesely/helenos/usb

Location:
uspace/drv/bus/usb/vhc
Files:
3 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/vhc/Makefile

    r5b18137 rb4b534ac  
    4949        hub/virthubops.c \
    5050        conndev.c \
    51         connhost.c \
    5251        devconn.c \
    53         hub.c \
    5452        main.c \
    5553        transfer.c
  • uspace/drv/bus/usb/vhc/conndev.c

    r5b18137 rb4b534ac  
    3838#include <ddf/driver.h>
    3939#include <usbvirt/ipc.h>
     40#include <usb/debug.h>
    4041#include <async.h>
    41 #include "conn.h"
     42
     43#include "vhcd.h"
    4244
    4345static fibril_local uintptr_t plugged_device_handle = 0;
     
    9496    ipc_call_t *icall)
    9597{
    96         vhc_data_t *vhc = ddf_dev_data_get(ddf_fun_get_dev(fun));
     98        vhc_data_t *vhc = ddf_fun_data_get(fun);
    9799       
    98100        async_sess_t *callback =
     
    125127void on_client_close(ddf_fun_t *fun)
    126128{
    127         vhc_data_t *vhc = ddf_dev_data_get(ddf_fun_get_dev(fun));
     129        vhc_data_t *vhc = ddf_fun_data_get(fun);
    128130
    129131        if (plugged_device_handle != 0) {
  • uspace/drv/bus/usb/vhc/devconn.c

    r5b18137 rb4b534ac  
    5151static int vhc_virtdev_plug_generic(vhc_data_t *vhc,
    5252    async_sess_t *sess, usbvirt_device_t *virtdev,
    53     uintptr_t *handle, bool connect)
     53    uintptr_t *handle, bool connect, usb_address_t address)
    5454{
    5555        vhc_virtdev_t *dev = vhc_virtdev_create();
     
    6060        dev->dev_sess = sess;
    6161        dev->dev_local = virtdev;
     62        dev->address = address;
    6263
    6364        fibril_mutex_lock(&vhc->guard);
     
    7879        if (connect) {
    7980                // FIXME: check status
    80                 (void) virthub_connect_device(vhc->hub, dev);
     81                (void) virthub_connect_device(&vhc->hub, dev);
    8182        }
    8283
     
    8687int vhc_virtdev_plug(vhc_data_t *vhc, async_sess_t *sess, uintptr_t *handle)
    8788{
    88         return vhc_virtdev_plug_generic(vhc, sess, NULL, handle, true);
     89        return vhc_virtdev_plug_generic(vhc, sess, NULL, handle, true, 0);
    8990}
    9091
    9192int vhc_virtdev_plug_local(vhc_data_t *vhc, usbvirt_device_t *dev, uintptr_t *handle)
    9293{
    93         return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, true);
     94        return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, true, 0);
    9495}
    9596
    96 int vhc_virtdev_plug_hub(vhc_data_t *vhc, usbvirt_device_t *dev, uintptr_t *handle)
     97int vhc_virtdev_plug_hub(vhc_data_t *vhc, usbvirt_device_t *dev, uintptr_t *handle, usb_address_t address)
    9798{
    98         return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, false);
     99        return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, false, address);
    99100}
    100101
     
    104105
    105106        // FIXME: check status
    106         (void) virthub_disconnect_device(vhc->hub, dev);
     107        (void) virthub_disconnect_device(&vhc->hub, dev);
    107108
    108109        fibril_mutex_lock(&vhc->guard);
  • uspace/drv/bus/usb/vhc/hub/virthub.c

    r5b18137 rb4b534ac  
    3434 */
    3535#include <usb/classes/classes.h>
     36#include <usb/classes/hub.h>
    3637#include <usbvirt/device.h>
    3738#include <assert.h>
    3839#include <errno.h>
    3940#include <str_error.h>
     41#include <stdio.h>
    4042#include <stdlib.h>
    4143#include <ddf/driver.h>
     
    7577        .type = USB_DESCTYPE_HUB,
    7678        .port_count = HUB_PORT_COUNT,
    77         .characteristics = 0,
     79        .characteristics = HUB_CHAR_NO_POWER_SWITCH_FLAG | HUB_CHAR_NO_OC_FLAG,
    7880        .power_on_warm_up = 50, /* Huh? */
    7981        .max_current = 100, /* Huh again. */
     
    9698        .length = sizeof(usb_standard_configuration_descriptor_t),
    9799        .descriptor_type = USB_DESCTYPE_CONFIGURATION,
    98         .total_length = 
     100        .total_length =
    99101                sizeof(usb_standard_configuration_descriptor_t)
    100102                + sizeof(std_interface_descriptor)
     
    144146 * @return Error code.
    145147 */
    146 int virthub_init(usbvirt_device_t *dev)
     148int virthub_init(usbvirt_device_t *dev, const char* name)
    147149{
    148150        if (dev == NULL) {
     
    151153        dev->ops = &hub_ops;
    152154        dev->descriptors = &descriptors;
     155        dev->address = 0;
     156        dev->name = str_dup(name);
     157        if (!dev->name)
     158                return ENOMEM;
    153159
    154160        hub_t *hub = malloc(sizeof(hub_t));
    155161        if (hub == NULL) {
     162                free(dev->name);
    156163                return ENOMEM;
    157164        }
  • uspace/drv/bus/usb/vhc/hub/virthub.h

    r5b18137 rb4b534ac  
    7979extern hub_descriptor_t hub_descriptor;
    8080
    81 int virthub_init(usbvirt_device_t *);
     81int virthub_init(usbvirt_device_t *, const char *name);
    8282int virthub_connect_device(usbvirt_device_t *, vhc_virtdev_t *);
    8383int virthub_disconnect_device(usbvirt_device_t *, vhc_virtdev_t *);
  • uspace/drv/bus/usb/vhc/hub/virthubops.c

    r5b18137 rb4b534ac  
    340340
    341341
    342 /** IN class request. */
    343 #define CLASS_REQ_IN(recipient) \
    344         USBVIRT_MAKE_CONTROL_REQUEST_TYPE(USB_DIRECTION_IN, \
    345         USBVIRT_REQUEST_TYPE_CLASS, recipient)
    346 /** OUT class request. */
    347 #define CLASS_REQ_OUT(recipient) \
    348         USBVIRT_MAKE_CONTROL_REQUEST_TYPE(USB_DIRECTION_OUT, \
    349         USBVIRT_REQUEST_TYPE_CLASS, recipient)
    350342
    351343/** Recipient: other. */
     
    353345/** Recipient: device. */
    354346#define REC_DEVICE USB_REQUEST_RECIPIENT_DEVICE
    355 /** Direction: in. */
    356 #define DIR_IN USB_DIRECTION_IN
    357 /** Direction: out. */
    358 #define DIR_OUT USB_DIRECTION_OUT
    359 
    360 
    361 /** Create a class request.
    362  *
    363  * @param direction Request direction.
    364  * @param recipient Request recipient.
    365  * @param req Request code.
    366  */
    367 #define CLASS_REQ(direction, recipient, req) \
    368         .req_direction = direction, \
    369         .req_recipient = recipient, \
    370         .req_type = USB_REQUEST_TYPE_CLASS, \
    371         .request = req
    372 
    373 /** Create a standard request.
    374  *
    375  * @param direction Request direction.
    376  * @param recipient Request recipient.
    377  * @param req Request code.
    378  */
    379 #define STD_REQ(direction, recipient, req) \
    380         .req_direction = direction, \
    381         .req_recipient = recipient, \
    382         .req_type = USB_REQUEST_TYPE_STANDARD, \
    383         .request = req
     347
    384348
    385349/** Hub operations on control endpoint zero. */
    386350static usbvirt_control_request_handler_t endpoint_zero_handlers[] = {
    387351        {
    388                 STD_REQ(DIR_IN, REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
    389                 .name = "GetDescriptor",
     352                STD_REQ_IN(USB_REQUEST_RECIPIENT_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
     353                .name = "GetStdDescriptor",
    390354                .callback = req_get_descriptor
    391355        },
    392356        {
    393                 CLASS_REQ(DIR_IN, REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
    394                 .name = "GetDescriptor",
     357                CLASS_REQ_IN(REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
     358                .name = "GetClassDescriptor",
    395359                .callback = req_get_descriptor
    396360        },
    397361        {
    398                 CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATUS),
     362                CLASS_REQ_IN(REC_OTHER, USB_HUB_REQUEST_GET_STATUS),
    399363                .name = "GetPortStatus",
    400364                .callback = req_get_port_status
    401365        },
    402366        {
    403                 CLASS_REQ(DIR_OUT, REC_DEVICE, USB_HUB_REQUEST_CLEAR_FEATURE),
     367                CLASS_REQ_OUT(REC_DEVICE, USB_HUB_REQUEST_CLEAR_FEATURE),
    404368                .name = "ClearHubFeature",
    405369                .callback = req_clear_hub_feature
    406370        },
    407371        {
    408                 CLASS_REQ(DIR_OUT, REC_OTHER, USB_HUB_REQUEST_CLEAR_FEATURE),
     372                CLASS_REQ_OUT(REC_OTHER, USB_HUB_REQUEST_CLEAR_FEATURE),
    409373                .name = "ClearPortFeature",
    410374                .callback = req_clear_port_feature
    411375        },
    412376        {
    413                 CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATE),
     377                CLASS_REQ_IN(REC_OTHER, USB_HUB_REQUEST_GET_STATE),
    414378                .name = "GetBusState",
    415379                .callback = req_get_bus_state
    416380        },
    417381        {
    418                 CLASS_REQ(DIR_IN, REC_DEVICE, USB_HUB_REQUEST_GET_DESCRIPTOR),
     382                CLASS_REQ_IN(REC_DEVICE, USB_HUB_REQUEST_GET_DESCRIPTOR),
    419383                .name = "GetHubDescriptor",
    420384                .callback = req_get_descriptor
    421385        },
    422386        {
    423                 CLASS_REQ(DIR_IN, REC_DEVICE, USB_HUB_REQUEST_GET_STATUS),
     387                CLASS_REQ_IN(REC_DEVICE, USB_HUB_REQUEST_GET_STATUS),
    424388                .name = "GetHubStatus",
    425389                .callback = req_get_hub_status
    426390        },
    427391        {
    428                 CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATUS),
     392                CLASS_REQ_IN(REC_OTHER, USB_HUB_REQUEST_GET_STATUS),
    429393                .name = "GetPortStatus",
    430394                .callback = req_get_port_status
    431395        },
    432396        {
    433                 CLASS_REQ(DIR_OUT, REC_DEVICE, USB_HUB_REQUEST_SET_FEATURE),
     397                CLASS_REQ_OUT(REC_DEVICE, USB_HUB_REQUEST_SET_FEATURE),
    434398                .name = "SetHubFeature",
    435399                .callback = req_set_hub_feature
    436400        },
    437401        {
    438                 CLASS_REQ(DIR_OUT, REC_OTHER, USB_HUB_REQUEST_SET_FEATURE),
     402                CLASS_REQ_OUT(REC_OTHER, USB_HUB_REQUEST_SET_FEATURE),
    439403                .name = "SetPortFeature",
    440404                .callback = req_set_port_feature
  • uspace/drv/bus/usb/vhc/main.c

    r5b18137 rb4b534ac  
    3434 */
    3535
    36 #include <loc.h>
    37 #include <async.h>
    38 #include <unistd.h>
    39 #include <stdlib.h>
    40 #include <sysinfo.h>
    4136#include <stdio.h>
    4237#include <errno.h>
     
    4439#include <ddf/driver.h>
    4540
    46 #include <usb/usb.h>
    47 #include <usb/ddfiface.h>
    48 #include <usb_iface.h>
     41#include <usb/host/ddf_helpers.h>
     42
     43#include <usb/debug.h>
    4944#include "vhcd.h"
    50 #include "hub.h"
    51 #include "conn.h"
     45
    5246
    5347static ddf_dev_ops_t vhc_ops = {
    54         .interfaces[USBHC_DEV_IFACE] = &vhc_iface,
    55         .interfaces[USB_DEV_IFACE] = &vhc_usb_iface,
    5648        .close = on_client_close,
    5749        .default_handler = default_connection_handler
    5850};
    5951
     52static int vhc_control_node(ddf_dev_t *dev, ddf_fun_t **fun)
     53{
     54        assert(dev);
     55        assert(fun);
     56
     57        *fun = ddf_fun_create(dev, fun_exposed, "virtual");
     58        if (!*fun)
     59                return ENOMEM;
     60
     61        vhc_data_t *vhc = ddf_fun_data_alloc(*fun, sizeof(vhc_data_t));
     62        if (!vhc) {
     63                ddf_fun_destroy(*fun);
     64        }
     65        ddf_fun_set_ops(*fun, &vhc_ops);
     66        const int ret = ddf_fun_bind(*fun);
     67        if (ret != EOK) {
     68                ddf_fun_destroy(*fun);
     69                *fun = NULL;
     70                return ret;
     71        }
     72        vhc_init(vhc);
     73        return EOK;
     74}
     75
     76hcd_ops_t vhc_hc_ops = {
     77        .schedule = vhc_schedule,
     78};
     79
    6080static int vhc_dev_add(ddf_dev_t *dev)
    6181{
    62         static int vhc_count = 0;
    63         int rc;
     82        /* Initialize virtual structure */
     83        ddf_fun_t *ctl_fun = NULL;
     84        int ret = vhc_control_node(dev, &ctl_fun);
     85        if (ret != EOK) {
     86                usb_log_error("Failed to setup control node.\n");
     87                return ret;
     88        }
     89        vhc_data_t *data = ddf_fun_data_get(ctl_fun);
    6490
    65         if (vhc_count > 0) {
    66                 return ELIMIT;
     91        /* Initialize generic structures */
     92        ret = hcd_ddf_setup_hc(dev, USB_SPEED_FULL,
     93            BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
     94        if (ret != EOK) {
     95                usb_log_error("Failed to init HCD structures: %s.\n",
     96                   str_error(ret));
     97                ddf_fun_destroy(ctl_fun);
     98                return ret;
    6799        }
    68100
    69         vhc_data_t *data = ddf_dev_data_alloc(dev, sizeof(vhc_data_t));
    70         if (data == NULL) {
    71                 usb_log_fatal("Failed to allocate memory.\n");
    72                 return ENOMEM;
    73         }
    74         data->magic = 0xDEADBEEF;
    75         rc = usb_endpoint_manager_init(&data->ep_manager, (size_t) -1,
    76             bandwidth_count_usb11);
    77         if (rc != EOK) {
    78                 usb_log_fatal("Failed to initialize endpoint manager.\n");
    79                 free(data);
    80                 return rc;
    81         }
    82         usb_device_manager_init(&data->dev_manager, USB_SPEED_MAX);
     101        hcd_set_implementation(dev_to_hcd(dev), data, &vhc_hc_ops);
    83102
    84         ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
    85         if (hc == NULL) {
    86                 usb_log_fatal("Failed to create device function.\n");
    87                 free(data);
    88                 return ENOMEM;
     103        /* Add virtual hub device */
     104        ret = vhc_virtdev_plug_hub(data, &data->hub, NULL, 0);
     105        if (ret != EOK) {
     106                usb_log_error("Failed to plug root hub: %s.\n", str_error(ret));
     107                ddf_fun_destroy(ctl_fun);
     108                return ret;
    89109        }
    90110
    91         ddf_fun_set_ops(hc, &vhc_ops);
    92         list_initialize(&data->devices);
    93         fibril_mutex_initialize(&data->guard);
    94         data->hub = &virtual_hub_device;
    95         data->hc_fun = hc;
    96 
    97         rc = ddf_fun_bind(hc);
    98         if (rc != EOK) {
    99                 usb_log_fatal("Failed to bind HC function: %s.\n",
    100                     str_error(rc));
    101                 free(data);
    102                 return rc;
     111        /*
     112         * Creating root hub registers a new USB device so HC
     113         * needs to be ready at this time.
     114         */
     115        ret = hcd_ddf_setup_root_hub(dev);
     116        if (ret != EOK) {
     117                usb_log_error("Failed to init VHC root hub: %s\n",
     118                        str_error(ret));
     119                // TODO do something here...
    103120        }
    104121
    105         rc = ddf_fun_add_to_category(hc, USB_HC_CATEGORY);
    106         if (rc != EOK) {
    107                 usb_log_fatal("Failed to add function to HC class: %s.\n",
    108                     str_error(rc));
    109                 free(data);
    110                 return rc;
    111         }
    112 
    113         virtual_hub_device_init(hc);
    114 
    115         usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n",
    116             (size_t) ddf_dev_get_handle(dev), (size_t) ddf_fun_get_handle(hc));
    117 
    118         rc = vhc_virtdev_plug_hub(data, data->hub, NULL);
    119         if (rc != EOK) {
    120                 usb_log_fatal("Failed to plug root hub: %s.\n", str_error(rc));
    121                 free(data);
    122                 return rc;
    123         }
    124 
    125         return EOK;
     122        return ret;
    126123}
    127124
     
    135132};
    136133
    137 
    138134int main(int argc, char * argv[])
    139 {       
     135{
    140136        log_init(NAME);
    141 
    142137        printf(NAME ": virtual USB host controller driver.\n");
    143138
     
    145140}
    146141
    147 
    148142/**
    149143 * @}
  • uspace/drv/bus/usb/vhc/transfer.c

    r5b18137 rb4b534ac  
    2929#include <errno.h>
    3030#include <str_error.h>
     31#include <usb/debug.h>
    3132#include <usbvirt/device.h>
    3233#include <usbvirt/ipc.h>
    3334#include "vhcd.h"
    34 
    35 vhc_transfer_t *vhc_transfer_create(usb_address_t address, usb_endpoint_t ep,
    36     usb_direction_t dir, usb_transfer_type_t tr_type,
    37     ddf_fun_t *fun, void *callback_arg)
    38 {
    39         vhc_transfer_t *result = malloc(sizeof(vhc_transfer_t));
    40         if (result == NULL) {
    41                 return NULL;
    42         }
    43         link_initialize(&result->link);
    44         result->address = address;
    45         result->endpoint = ep;
    46         result->direction = dir;
    47         result->transfer_type = tr_type;
    48         result->setup_buffer = NULL;
    49         result->setup_buffer_size = 0;
    50         result->data_buffer = NULL;
    51         result->data_buffer_size = 0;
    52         result->ddf_fun = fun;
    53         result->callback_arg = callback_arg;
    54         result->callback_in = NULL;
    55         result->callback_out = NULL;
    56 
    57         usb_log_debug2("Created transfer %p (%d.%d %s %s)\n", result,
    58             address, ep, usb_str_transfer_type_short(tr_type),
    59             dir == USB_DIRECTION_IN ? "in" : "out");
    60 
    61         return result;
    62 }
     35#include "hub/virthub.h"
    6336
    6437static bool is_set_address_transfer(vhc_transfer_t *transfer)
    6538{
    66         if (transfer->endpoint != 0) {
    67                 return false;
    68         }
    69         if (transfer->transfer_type != USB_TRANSFER_CONTROL) {
    70                 return false;
    71         }
    72         if (transfer->direction != USB_DIRECTION_OUT) {
    73                 return false;
    74         }
    75         if (transfer->setup_buffer_size != sizeof(usb_device_request_setup_packet_t)) {
    76                 return false;
    77         }
    78         usb_device_request_setup_packet_t *setup = transfer->setup_buffer;
     39        if (transfer->batch->ep->endpoint != 0) {
     40                return false;
     41        }
     42        if (transfer->batch->ep->transfer_type != USB_TRANSFER_CONTROL) {
     43                return false;
     44        }
     45        if (usb_transfer_batch_direction(transfer->batch) != USB_DIRECTION_OUT) {
     46                return false;
     47        }
     48        const usb_device_request_setup_packet_t *setup =
     49            (void*)transfer->batch->setup_buffer;
    7950        if (setup->request_type != 0) {
    8051                return false;
     
    8758}
    8859
    89 int vhc_virtdev_add_transfer(vhc_data_t *vhc, vhc_transfer_t *transfer)
    90 {
    91         fibril_mutex_lock(&vhc->guard);
    92 
    93         bool target_found = false;
    94         list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
    95                 fibril_mutex_lock(&dev->guard);
    96                 if (dev->address == transfer->address) {
    97                         if (target_found) {
    98                                 usb_log_warning("Transfer would be accepted by more devices!\n");
    99                                 goto next;
    100                         }
    101                         target_found = true;
    102                         list_append(&transfer->link, &dev->transfer_queue);
    103                 }
    104 next:
    105                 fibril_mutex_unlock(&dev->guard);
    106         }
    107 
    108         fibril_mutex_unlock(&vhc->guard);
    109 
    110         if (target_found) {
    111                 return EOK;
     60static int process_transfer_local(usb_transfer_batch_t *batch,
     61    usbvirt_device_t *dev, size_t *actual_data_size)
     62{
     63        int rc;
     64       
     65        const usb_direction_t dir = usb_transfer_batch_direction(batch);
     66
     67        if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
     68                if (dir == USB_DIRECTION_IN) {
     69                        rc = usbvirt_control_read(dev,
     70                            batch->setup_buffer, batch->setup_size,
     71                            batch->buffer, batch->buffer_size,
     72                            actual_data_size);
     73                } else {
     74                        assert(dir == USB_DIRECTION_OUT);
     75                        rc = usbvirt_control_write(dev,
     76                            batch->setup_buffer, batch->setup_size,
     77                            batch->buffer, batch->buffer_size);
     78                }
    11279        } else {
    113                 return ENOENT;
    114         }
    115 }
    116 
    117 static int process_transfer_local(vhc_transfer_t *transfer,
    118     usbvirt_device_t *dev, size_t *actual_data_size)
     80                if (dir == USB_DIRECTION_IN) {
     81                        rc = usbvirt_data_in(dev, batch->ep->transfer_type,
     82                            batch->ep->endpoint,
     83                            batch->buffer, batch->buffer_size,
     84                            actual_data_size);
     85                } else {
     86                        assert(dir == USB_DIRECTION_OUT);
     87                        rc = usbvirt_data_out(dev, batch->ep->transfer_type,
     88                            batch->ep->endpoint,
     89                            batch->buffer, batch->buffer_size);
     90                }
     91        }
     92
     93        return rc;
     94}
     95
     96static int process_transfer_remote(usb_transfer_batch_t *batch,
     97    async_sess_t *sess, size_t *actual_data_size)
    11998{
    12099        int rc;
    121100
    122         if (transfer->transfer_type == USB_TRANSFER_CONTROL) {
    123                 if (transfer->direction == USB_DIRECTION_IN) {
    124                         rc = usbvirt_control_read(dev,
    125                             transfer->setup_buffer, transfer->setup_buffer_size,
    126                             transfer->data_buffer, transfer->data_buffer_size,
    127                             actual_data_size);
    128                 } else {
    129                         assert(transfer->direction == USB_DIRECTION_OUT);
    130                         rc = usbvirt_control_write(dev,
    131                             transfer->setup_buffer, transfer->setup_buffer_size,
    132                             transfer->data_buffer, transfer->data_buffer_size);
     101        const usb_direction_t dir = usb_transfer_batch_direction(batch);
     102
     103        if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
     104                if (dir == USB_DIRECTION_IN) {
     105                        rc = usbvirt_ipc_send_control_read(sess,
     106                            batch->setup_buffer, batch->setup_size,
     107                            batch->buffer, batch->buffer_size,
     108                            actual_data_size);
     109                } else {
     110                        assert(dir == USB_DIRECTION_OUT);
     111                        rc = usbvirt_ipc_send_control_write(sess,
     112                            batch->setup_buffer, batch->setup_size,
     113                            batch->buffer, batch->buffer_size);
    133114                }
    134115        } else {
    135                 if (transfer->direction == USB_DIRECTION_IN) {
    136                         rc = usbvirt_data_in(dev, transfer->transfer_type,
    137                             transfer->endpoint,
    138                             transfer->data_buffer, transfer->data_buffer_size,
    139                             actual_data_size);
    140                 } else {
    141                         assert(transfer->direction == USB_DIRECTION_OUT);
    142                         rc = usbvirt_data_out(dev, transfer->transfer_type,
    143                             transfer->endpoint,
    144                             transfer->data_buffer, transfer->data_buffer_size);
    145                 }
    146         }
    147 
    148         return rc;
    149 }
    150 
    151 static int process_transfer_remote(vhc_transfer_t *transfer,
    152     async_sess_t *sess, size_t *actual_data_size)
    153 {
    154         int rc;
    155 
    156         if (transfer->transfer_type == USB_TRANSFER_CONTROL) {
    157                 if (transfer->direction == USB_DIRECTION_IN) {
    158                         rc = usbvirt_ipc_send_control_read(sess,
    159                             transfer->setup_buffer, transfer->setup_buffer_size,
    160                             transfer->data_buffer, transfer->data_buffer_size,
    161                             actual_data_size);
    162                 } else {
    163                         assert(transfer->direction == USB_DIRECTION_OUT);
    164                         rc = usbvirt_ipc_send_control_write(sess,
    165                             transfer->setup_buffer, transfer->setup_buffer_size,
    166                             transfer->data_buffer, transfer->data_buffer_size);
    167                 }
    168         } else {
    169                 if (transfer->direction == USB_DIRECTION_IN) {
    170                         rc = usbvirt_ipc_send_data_in(sess, transfer->endpoint,
    171                             transfer->transfer_type,
    172                             transfer->data_buffer, transfer->data_buffer_size,
    173                             actual_data_size);
    174                 } else {
    175                         assert(transfer->direction == USB_DIRECTION_OUT);
    176                         rc = usbvirt_ipc_send_data_out(sess, transfer->endpoint,
    177                             transfer->transfer_type,
    178                             transfer->data_buffer, transfer->data_buffer_size);
     116                if (dir == USB_DIRECTION_IN) {
     117                        rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
     118                            batch->ep->transfer_type,
     119                            batch->buffer, batch->buffer_size,
     120                            actual_data_size);
     121                } else {
     122                        assert(dir == USB_DIRECTION_OUT);
     123                        rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
     124                            batch->ep->transfer_type,
     125                            batch->buffer, batch->buffer_size);
    179126                }
    180127        }
     
    195142}
    196143
    197 
    198144static void execute_transfer_callback_and_free(vhc_transfer_t *transfer,
    199145    size_t data_transfer_size, int outcome)
    200146{
    201147        assert(outcome != ENAK);
    202 
    203         usb_log_debug2("Transfer %p ended: %s.\n",
    204             transfer, str_error(outcome));
    205 
    206         if (transfer->direction == USB_DIRECTION_IN) {
    207                 transfer->callback_in(transfer->ddf_fun, outcome,
    208                     data_transfer_size, transfer->callback_arg);
    209         } else {
    210                 assert(transfer->direction == USB_DIRECTION_OUT);
    211                 transfer->callback_out(transfer->ddf_fun, outcome,
    212                     transfer->callback_arg);
    213         }
    214 
     148        assert(transfer);
     149        assert(transfer->batch);
     150        usb_transfer_batch_finish_error(transfer->batch, NULL,
     151            data_transfer_size, outcome);
     152        usb_transfer_batch_destroy(transfer->batch);
    215153        free(transfer);
     154}
     155
     156int vhc_init(vhc_data_t *instance)
     157{
     158        assert(instance);
     159        list_initialize(&instance->devices);
     160        fibril_mutex_initialize(&instance->guard);
     161        instance->magic = 0xDEADBEEF;
     162        return virthub_init(&instance->hub, "root hub");
     163}
     164
     165int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
     166{
     167        assert(hcd);
     168        assert(batch);
     169        vhc_data_t *vhc = hcd_get_driver_data(hcd);
     170        assert(vhc);
     171
     172        vhc_transfer_t *transfer = malloc(sizeof(vhc_transfer_t));
     173        if (!transfer)
     174                return ENOMEM;
     175        link_initialize(&transfer->link);
     176        transfer->batch = batch;
     177
     178        fibril_mutex_lock(&vhc->guard);
     179
     180        int targets = 0;
     181
     182        list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
     183                fibril_mutex_lock(&dev->guard);
     184                if (dev->address == transfer->batch->ep->address) {
     185                        if (!targets) {
     186                                list_append(&transfer->link, &dev->transfer_queue);
     187                        }
     188                        ++targets;
     189                }
     190                fibril_mutex_unlock(&dev->guard);
     191        }
     192
     193        fibril_mutex_unlock(&vhc->guard);
     194       
     195        if (targets > 1)
     196                usb_log_warning("Transfer would be accepted by more devices!\n");
     197
     198        return targets ? EOK : ENOENT;
    216199}
    217200
     
    234217                size_t data_transfer_size = 0;
    235218                if (dev->dev_sess) {
    236                         rc = process_transfer_remote(transfer, dev->dev_sess,
    237                             &data_transfer_size);
     219                        rc = process_transfer_remote(transfer->batch,
     220                            dev->dev_sess, &data_transfer_size);
    238221                } else if (dev->dev_local != NULL) {
    239                         rc = process_transfer_local(transfer, dev->dev_local,
    240                             &data_transfer_size);
     222                        rc = process_transfer_local(transfer->batch,
     223                            dev->dev_local, &data_transfer_size);
    241224                } else {
    242225                        usb_log_warning("Device has no remote phone nor local node.\n");
     
    251234                        if (is_set_address_transfer(transfer)) {
    252235                                usb_device_request_setup_packet_t *setup
    253                                     = transfer->setup_buffer;
     236                                    = (void*)transfer->batch->setup_buffer;
    254237                                dev->address = setup->value;
    255238                                usb_log_debug2("Address changed to %d\n",
     
    284267        return EOK;
    285268}
    286 
  • uspace/drv/bus/usb/vhc/vhcd.h

    r5b18137 rb4b534ac  
    3636#define VHCD_VHCD_H_
    3737
    38 #include <usb/debug.h>
    3938#include <usbvirt/device.h>
    40 #include <usb/host/usb_endpoint_manager.h>
    41 #include <usb/host/usb_device_manager.h>
    4239#include <usbhc_iface.h>
    4340#include <async.h>
     41
     42#include <usb/host/hcd.h>
     43
    4444
    4545#define NAME "vhc"
     
    5959        list_t devices;
    6060        fibril_mutex_t guard;
    61         usb_endpoint_manager_t ep_manager;
    62         usb_device_manager_t dev_manager;
    63         usbvirt_device_t *hub;
    64         ddf_fun_t *hc_fun;
     61        usbvirt_device_t hub;
    6562} vhc_data_t;
    6663
    6764typedef struct {
    6865        link_t link;
    69         usb_address_t address;
    70         usb_endpoint_t endpoint;
    71         usb_direction_t direction;
    72         usb_transfer_type_t transfer_type;
    73         void *setup_buffer;
    74         size_t setup_buffer_size;
    75         void *data_buffer;
    76         size_t data_buffer_size;
    77         ddf_fun_t *ddf_fun;
    78         void *callback_arg;
    79         usbhc_iface_transfer_in_callback_t callback_in;
    80         usbhc_iface_transfer_out_callback_t callback_out;
     66        usb_transfer_batch_t *batch;
    8167} vhc_transfer_t;
    8268
    83 vhc_transfer_t *vhc_transfer_create(usb_address_t, usb_endpoint_t,
    84     usb_direction_t, usb_transfer_type_t, ddf_fun_t *, void *);
     69
     70void on_client_close(ddf_fun_t *fun);
     71void default_connection_handler(ddf_fun_t *fun, ipc_callid_t icallid,
     72    ipc_call_t *icall);
     73
    8574int vhc_virtdev_plug(vhc_data_t *, async_sess_t *, uintptr_t *);
    8675int vhc_virtdev_plug_local(vhc_data_t *, usbvirt_device_t *, uintptr_t *);
    87 int vhc_virtdev_plug_hub(vhc_data_t *, usbvirt_device_t *, uintptr_t *);
     76int vhc_virtdev_plug_hub(vhc_data_t *, usbvirt_device_t *, uintptr_t *, usb_address_t address);
    8877void vhc_virtdev_unplug(vhc_data_t *, uintptr_t);
    89 int vhc_virtdev_add_transfer(vhc_data_t *, vhc_transfer_t *);
    9078
     79int vhc_init(vhc_data_t *instance);
     80int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    9181int vhc_transfer_queue_processor(void *arg);
    92 
    9382
    9483#endif
Note: See TracChangeset for help on using the changeset viewer.