Changeset 138a7fd in mainline


Ignore:
Timestamp:
2010-12-12T17:05:55Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a39f4cf, ecf52c4b
Parents:
c9113d2
Message:

Fixes & improvements in virtual hub

The changes includes:

  • unified (a bit) debugging output
  • port is put into power-off state after SET_CONFIGURATION request
  • less ports on the hub
  • delayed port changes run in separate fibril
  • shorter waiting for transactions in HC scheduling manager
Location:
uspace/drv
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci/main.c

    rc9113d2 r138a7fd  
    2929#include <usb/debug.h>
    3030#include <errno.h>
     31#include <driver.h>
    3132#include "uhci.h"
    3233
  • uspace/drv/vhc/connhost.c

    rc9113d2 r138a7fd  
    9393    usbhc_iface_transfer_out_callback_t callback, void *arg)
    9494{
    95         printf(NAME ": transfer OUT [%d.%d (%s); %zu]\n",
     95        dprintf(1, "transfer OUT [%d.%d (%s); %zu]",
    9696            target.address, target.endpoint,
    9797            usb_str_transfer_type(transfer_type),
     
    113113    usbhc_iface_transfer_out_callback_t callback, void *arg)
    114114{
    115         printf(NAME ": transfer SETUP [%d.%d (%s); %zu]\n",
     115        dprintf(1, "transfer SETUP [%d.%d (%s); %zu]",
    116116            target.address, target.endpoint,
    117117            usb_str_transfer_type(transfer_type),
     
    133133    usbhc_iface_transfer_in_callback_t callback, void *arg)
    134134{
    135         printf(NAME ": transfer IN [%d.%d (%s); %zu]\n",
     135        dprintf(1, "transfer IN [%d.%d (%s); %zu]",
    136136            target.address, target.endpoint,
    137137            usb_str_transfer_type(transfer_type),
  • uspace/drv/vhc/hc.c

    rc9113d2 r138a7fd  
    5050#include "hub.h"
    5151
    52 #define USLEEP_BASE (500 * 1000)
     52#define USLEEP_BASE (0 * 500 * 1000)
    5353
    5454#define USLEEP_VAR 5000
     
    116116                char ports[HUB_PORT_COUNT + 2];
    117117                hub_get_port_statuses(ports, HUB_PORT_COUNT + 1);
    118                 dprintf(3, "virtual hub: addr=%d ports=%s",
     118                dprintf(0, "virtual hub: addr=%d ports=%s",
    119119                    virthub_dev.address, ports);
    120120               
  • uspace/drv/vhc/hcd.c

    rc9113d2 r138a7fd  
    110110        printf("%s: virtual USB host controller driver.\n", NAME);
    111111
    112         usb_dprintf_enable(NAME, 10);
     112        usb_dprintf_enable(NAME, 1);
    113113
    114114        fid_t fid = fibril_create(hc_manager_fibril, NULL);
  • uspace/drv/vhc/hub.c

    rc9113d2 r138a7fd  
    144144        .ops = &hub_ops,
    145145        .descriptors = &descriptors,
    146         .lib_debug_level = 4,
     146        .lib_debug_level = 1,
    147147        .lib_debug_enabled_tags = USBVIRT_DEBUGTAG_ALL
    148148};
     
    177177{
    178178        size_t i;
     179       
    179180        for (i = 0; i < HUB_PORT_COUNT; i++) {
    180181                hub_port_t *port = &hub_dev.ports[i];
    181182               
     183                port->index = (int) i;
    182184                port->device = NULL;
    183185                port->state = HUB_PORT_STATE_NOT_CONFIGURED;
  • uspace/drv/vhc/hub.h

    rc9113d2 r138a7fd  
    4141#include "devices.h"
    4242
    43 #define HUB_PORT_COUNT 6
     43#define HUB_PORT_COUNT 2
    4444
    4545#define BITS2BYTES(bits) \
  • uspace/drv/vhc/hubintern.h

    rc9113d2 r138a7fd  
    121121typedef struct {
    122122        virtdev_connection_t *device;
     123        int index;
    123124        hub_port_state_t state;
    124125        uint16_t status_change;
  • uspace/drv/vhc/hubops.c

    rc9113d2 r138a7fd  
    5959static int on_get_descriptor(struct usbvirt_device *dev,
    6060    usb_device_request_setup_packet_t *request, uint8_t *data);
     61static int on_set_configuration(struct usbvirt_device *dev,
     62    usb_device_request_setup_packet_t *request, uint8_t *data);
    6163static int on_class_request(struct usbvirt_device *dev,
    6264    usb_device_request_setup_packet_t *request, uint8_t *data);
     
    6466    usb_endpoint_t endpoint,
    6567    void *buffer, size_t size, size_t *actual_size);
     68static void set_port_state(hub_port_t *, hub_port_state_t);
    6669
    6770/** Standard USB requests. */
     
    7477        .on_set_descriptor = NULL,
    7578        .on_get_configuration = NULL,
    76         .on_set_configuration = NULL,
     79        .on_set_configuration = on_set_configuration,
    7780        .on_get_interface = NULL,
    7881        .on_set_interface = NULL,
     
    102105}
    103106
     107/** Callback for SET_CONFIGURATION request. */
     108int on_set_configuration(struct usbvirt_device *dev,
     109    usb_device_request_setup_packet_t *request, uint8_t *data)
     110{
     111        /* We must suspend power source to all ports. */
     112        size_t i;
     113        for (i = 0; i < HUB_PORT_COUNT; i++) {
     114                hub_port_t *port = &hub_dev.ports[i];
     115               
     116                set_port_state(port, HUB_PORT_STATE_POWERED_OFF);
     117        }
     118       
     119        /* Let the framework handle the rest of the job. */
     120        return EFORWARD;
     121}
     122
     123struct delay_port_state_change {
     124        suseconds_t delay;
     125        hub_port_state_t old_state;
     126        hub_port_state_t new_state;
     127        hub_port_t *port;
     128};
     129
     130static int set_port_state_delayed_fibril(void *arg)
     131{
     132        struct delay_port_state_change *change
     133            = (struct delay_port_state_change *) arg;
     134       
     135        async_usleep(change->delay);
     136       
     137        if (change->port->state == change->old_state) {
     138                set_port_state(change->port, change->new_state);
     139        }
     140       
     141        free(change);
     142       
     143        return EOK;
     144}
     145
     146static void set_port_state_delayed(hub_port_t *port,
     147    suseconds_t delay_time,
     148    hub_port_state_t old_state, hub_port_state_t new_state)
     149{
     150        struct delay_port_state_change *change
     151            = malloc(sizeof(struct delay_port_state_change));
     152        change->port = port;
     153        change->delay = delay_time;
     154        change->old_state = old_state;
     155        change->new_state = new_state;
     156        fid_t fibril = fibril_create(set_port_state_delayed_fibril, change);
     157        if (fibril == 0) {
     158                printf("Failed to create fibril\n");
     159                return;
     160        }
     161        fibril_add_ready(fibril);
     162}
     163
    104164/** Change port status and updates status change status fields.
    105165 */
    106 static void set_port_state(hub_port_t *port, hub_port_state_t state)
    107 {
    108         port->state = state;
     166void set_port_state(hub_port_t *port, hub_port_state_t state)
     167{
     168        dprintf(1, "setting port %d state to %d (%c)", port->index,
     169            state, hub_port_state_as_char(state));
     170       
    109171        if (state == HUB_PORT_STATE_POWERED_OFF) {
    110172                clear_port_status_change(port, HUB_STATUS_C_PORT_CONNECTION);
     
    113175        }
    114176        if (state == HUB_PORT_STATE_RESUMING) {
    115                 async_usleep(10*1000);
    116                 if (port->state == state) {
    117                         set_port_state(port, HUB_PORT_STATE_ENABLED);
    118                 }
     177                set_port_state_delayed(port, 10*1000,
     178                    HUB_PORT_STATE_RESUMING, HUB_PORT_STATE_ENABLED);
    119179        }
    120180        if (state == HUB_PORT_STATE_RESETTING) {
    121                 async_usleep(10*1000);
    122                 if (port->state == state) {
    123                         set_port_status_change(port, HUB_STATUS_C_PORT_RESET);
    124                         set_port_state(port, HUB_PORT_STATE_ENABLED);
    125                 }
    126         }
     181                set_port_state_delayed(port, 10*1000,
     182                    HUB_PORT_STATE_RESETTING, HUB_PORT_STATE_ENABLED);
     183        }
     184        if ((port->state == HUB_PORT_STATE_RESETTING)
     185            && (state == HUB_PORT_STATE_ENABLED)) {
     186                set_port_status_change(port, HUB_STATUS_C_PORT_RESET);
     187        }
     188       
     189        port->state = state;
    127190}
    128191
     
    249312        status |= (port->status_change << 16);
    250313       
     314        dprintf(2, "GetPortStatus(port=%d, status=%u)\n", (int)portindex,
     315            (unsigned int) status);
    251316        return virthub_dev.control_transfer_reply(&virthub_dev, 0, &status, 4);
    252317}
     
    291356    usb_device_request_setup_packet_t *request, uint8_t *data)
    292357{       
    293         dprintf(2, "hub class request (%d)\n", (int) request->request);
     358        dprintf(2, "hub class request (%d)", (int) request->request);
    294359       
    295360        uint8_t recipient = request->request_type & 31;
     
    340405                       
    341406                default:
     407                        dprintf(0, "WARN: unknown request (%d)!\n",
     408                            request->request);
    342409                        break;
    343410        }
Note: See TracChangeset for help on using the changeset viewer.