Changeset df6ded8 in mainline for uspace/drv/bus/usb/vhc/transfer.c


Ignore:
Timestamp:
2018-02-28T16:37:50Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1b20da0
Parents:
f5e5f73 (diff), b2dca8de (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.
git-author:
Jakub Jermar <jakub@…> (2018-02-28 16:06:42)
git-committer:
Jakub Jermar <jakub@…> (2018-02-28 16:37:50)
Message:

Merge github.com:helenos-xhci-team/helenos

This commit merges support for USB 3 and generally refactors, fixes,
extends and cleans up the existing USB framework.

Notable additions and features:

  • new host controller driver has been implemented to control various xHC models (among others, NEC Renesas uPD720200)
  • isochronous data transfer mode
  • support for explicit USB device removal
  • USB tablet driver
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/vhc/transfer.c

    rf5e5f73 rdf6ded8  
    11/*
    22 * Copyright (c) 2011 Vojtech Horky
     3 * Copyright (c) 2018 Ondrej Hlavaty
    34 * All rights reserved.
    45 *
     
    3132#include <usb/debug.h>
    3233#include <usbvirt/device.h>
     34#include <usb/host/bandwidth.h>
     35#include <usb/host/endpoint.h>
     36#include <usb/host/usb_transfer_batch.h>
    3337#include <usbvirt/ipc.h>
    3438#include "vhcd.h"
     
    3741static bool is_set_address_transfer(vhc_transfer_t *transfer)
    3842{
    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) {
     43        if (transfer->batch.target.endpoint != 0) {
     44                return false;
     45        }
     46        if (transfer->batch.ep->transfer_type != USB_TRANSFER_CONTROL) {
     47                return false;
     48        }
     49        if (transfer->batch.dir != USB_DIRECTION_OUT) {
    4650                return false;
    4751        }
    4852        const usb_device_request_setup_packet_t *setup =
    49             (void*)transfer->batch->setup_buffer;
     53            &transfer->batch.setup.packet;
    5054        if (setup->request_type != 0) {
    5155                return false;
     
    6266{
    6367        errno_t rc;
    64        
    65         const usb_direction_t dir = usb_transfer_batch_direction(batch);
     68
     69        const usb_direction_t dir = batch->dir;
    6670
    6771        if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
    6872                if (dir == USB_DIRECTION_IN) {
    6973                        rc = usbvirt_control_read(dev,
    70                             batch->setup_buffer, batch->setup_size,
    71                             batch->buffer, batch->buffer_size,
     74                            batch->setup.buffer, USB_SETUP_PACKET_SIZE,
     75                            batch->dma_buffer.virt, batch->size,
    7276                            actual_data_size);
    7377                } else {
    7478                        assert(dir == USB_DIRECTION_OUT);
    7579                        rc = usbvirt_control_write(dev,
    76                             batch->setup_buffer, batch->setup_size,
    77                             batch->buffer, batch->buffer_size);
     80                            batch->setup.buffer, USB_SETUP_PACKET_SIZE,
     81                            batch->dma_buffer.virt, batch->size);
    7882                }
    7983        } else {
     
    8185                        rc = usbvirt_data_in(dev, batch->ep->transfer_type,
    8286                            batch->ep->endpoint,
    83                             batch->buffer, batch->buffer_size,
     87                            batch->dma_buffer.virt, batch->size,
    8488                            actual_data_size);
    8589                } else {
     
    8791                        rc = usbvirt_data_out(dev, batch->ep->transfer_type,
    8892                            batch->ep->endpoint,
    89                             batch->buffer, batch->buffer_size);
     93                            batch->dma_buffer.virt, batch->size);
    9094                }
    9195        }
     
    99103        errno_t rc;
    100104
    101         const usb_direction_t dir = usb_transfer_batch_direction(batch);
     105        const usb_direction_t dir = batch->dir;
    102106
    103107        if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
    104108                if (dir == USB_DIRECTION_IN) {
    105109                        rc = usbvirt_ipc_send_control_read(sess,
    106                             batch->setup_buffer, batch->setup_size,
    107                             batch->buffer, batch->buffer_size,
     110                            batch->setup.buffer, USB_SETUP_PACKET_SIZE,
     111                            batch->dma_buffer.virt, batch->size,
    108112                            actual_data_size);
    109113                } else {
    110114                        assert(dir == USB_DIRECTION_OUT);
    111115                        rc = usbvirt_ipc_send_control_write(sess,
    112                             batch->setup_buffer, batch->setup_size,
    113                             batch->buffer, batch->buffer_size);
     116                            batch->setup.buffer, USB_SETUP_PACKET_SIZE,
     117                            batch->dma_buffer.virt, batch->size);
    114118                }
    115119        } else {
     
    117121                        rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
    118122                            batch->ep->transfer_type,
    119                             batch->buffer, batch->buffer_size,
     123                            batch->dma_buffer.virt, batch->size,
    120124                            actual_data_size);
    121125                } else {
     
    123127                        rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
    124128                            batch->ep->transfer_type,
    125                             batch->buffer, batch->buffer_size);
     129                            batch->dma_buffer.virt, batch->size);
    126130                }
    127131        }
     
    135139        assert(!list_empty(&dev->transfer_queue));
    136140
    137         vhc_transfer_t *transfer = list_get_instance(
    138             list_first(&dev->transfer_queue), vhc_transfer_t, link);
     141        vhc_transfer_t *transfer =
     142            list_get_instance(list_first(&dev->transfer_queue),
     143            vhc_transfer_t, link);
    139144        list_remove(&transfer->link);
    140145
     
    147152        assert(outcome != ENAK);
    148153        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);
    153         free(transfer);
    154 }
     154        transfer->batch.error = outcome;
     155        transfer->batch.transferred_size = data_transfer_size;
     156        usb_transfer_batch_finish(&transfer->batch);
     157}
     158
     159static usb_transfer_batch_t *batch_create(endpoint_t *ep)
     160{
     161        vhc_transfer_t *transfer = calloc(1, sizeof(vhc_transfer_t));
     162        usb_transfer_batch_init(&transfer->batch, ep);
     163        link_initialize(&transfer->link);
     164        return &transfer->batch;
     165}
     166
     167static int device_enumerate(device_t *device)
     168{
     169        vhc_data_t *vhc = bus_to_vhc(device->bus);
     170        return usb2_bus_device_enumerate(&vhc->bus_helper, device);
     171}
     172
     173static int endpoint_register(endpoint_t *endpoint)
     174{
     175        vhc_data_t *vhc = bus_to_vhc(endpoint->device->bus);
     176        return usb2_bus_endpoint_register(&vhc->bus_helper, endpoint);
     177}
     178
     179static void endpoint_unregister(endpoint_t *endpoint)
     180{
     181        vhc_data_t *vhc = bus_to_vhc(endpoint->device->bus);
     182        usb2_bus_endpoint_unregister(&vhc->bus_helper, endpoint);
     183
     184        // TODO: abort transfer?
     185}
     186
     187static const bus_ops_t vhc_bus_ops = {
     188        .batch_create = batch_create,
     189        .batch_schedule = vhc_schedule,
     190
     191        .device_enumerate = device_enumerate,
     192        .endpoint_register = endpoint_register,
     193        .endpoint_unregister = endpoint_unregister,
     194};
    155195
    156196errno_t vhc_init(vhc_data_t *instance)
     
    159199        list_initialize(&instance->devices);
    160200        fibril_mutex_initialize(&instance->guard);
    161         instance->magic = 0xDEADBEEF;
     201        bus_init(&instance->bus, sizeof(device_t));
     202        usb2_bus_helper_init(&instance->bus_helper, &bandwidth_accounting_usb11);
     203        instance->bus.ops = &vhc_bus_ops;
    162204        return virthub_init(&instance->hub, "root hub");
    163205}
    164206
    165 errno_t vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    166 {
    167         assert(hcd);
     207errno_t vhc_schedule(usb_transfer_batch_t *batch)
     208{
    168209        assert(batch);
    169         vhc_data_t *vhc = hcd_get_driver_data(hcd);
     210        vhc_transfer_t *transfer = (vhc_transfer_t *) batch;
     211        vhc_data_t *vhc = bus_to_vhc(endpoint_get_bus(batch->ep));
    170212        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;
    177213
    178214        fibril_mutex_lock(&vhc->guard);
     
    182218        list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
    183219                fibril_mutex_lock(&dev->guard);
    184                 if (dev->address == transfer->batch->ep->address) {
     220                if (dev->address == transfer->batch.target.address) {
    185221                        if (!targets) {
    186222                                list_append(&transfer->link, &dev->transfer_queue);
     
    194230       
    195231        if (targets > 1)
    196                 usb_log_warning("Transfer would be accepted by more devices!\n");
     232                usb_log_warning("Transfer would be accepted by more devices!");
    197233
    198234        return targets ? EOK : ENOENT;
     
    217253                size_t data_transfer_size = 0;
    218254                if (dev->dev_sess) {
    219                         rc = process_transfer_remote(transfer->batch,
     255                        rc = process_transfer_remote(&transfer->batch,
    220256                            dev->dev_sess, &data_transfer_size);
    221257                } else if (dev->dev_local != NULL) {
    222                         rc = process_transfer_local(transfer->batch,
     258                        rc = process_transfer_local(&transfer->batch,
    223259                            dev->dev_local, &data_transfer_size);
    224260                } else {
    225                         usb_log_warning("Device has no remote phone nor local node.\n");
     261                        usb_log_warning("Device has no remote phone "
     262                            "nor local node.");
    226263                        rc = ESTALL;
    227264                }
    228265
    229                 usb_log_debug2("Transfer %p processed: %s.\n",
     266                usb_log_debug2("Transfer %p processed: %s.",
    230267                    transfer, str_error(rc));
    231268
     
    234271                        if (is_set_address_transfer(transfer)) {
    235272                                usb_device_request_setup_packet_t *setup =
    236                                     (void*) transfer->batch->setup_buffer;
     273                                    (void *) transfer->batch.setup.buffer;
    237274                                dev->address = setup->value;
    238                                 usb_log_debug2("Address changed to %d\n",
     275                                usb_log_debug2("Address changed to %d",
    239276                                    dev->address);
    240277                        }
Note: See TracChangeset for help on using the changeset viewer.