Changeset c4e84ed6 in mainline for uspace/drv/bus/usb/usbhub/port.h


Ignore:
Timestamp:
2018-01-16T03:45:38Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c952abc4
Parents:
d2c3dcd
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-15 20:49:15)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-16 03:45:38)
Message:

usbhub: rewrite port handling

The state space of a usb hub port is a bit more complex than what was
there originally. Got rid of the active operations counting, and
replaced that with finite state machine. Fixes a lot of race conditions
and lack of synchronization when connect and disconnect events come very
fast.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhub/port.h

    rd2c3dcd rc4e84ed6  
    22 * Copyright (c) 2011 Vojtech Horky
    33 * Copyright (c) 2011 Jan Vesely
     4 * Copyright (c) 2017 Ondra Hlavaty
    45 * All rights reserved.
    56 *
     
    3233 */
    3334/** @file
    34  * Hub ports related functions.
     35 * Hub port state machine.
    3536 */
    3637
     
    4344typedef struct usb_hub_dev usb_hub_dev_t;
    4445
     46typedef enum {
     47        PORT_DISABLED,  /* No device connected. */
     48        PORT_CONNECTED, /* A device connected, not yet initialized. */
     49        PORT_IN_RESET,  /* An initial port reset in progress. */
     50        PORT_ENABLED,   /* Port reset complete, port enabled. Device announced to the HC. */
     51        PORT_ERROR,     /* An error occured. There is still a fibril that needs to know it. */
     52} port_state_t;
     53
    4554/** Information about single port on a hub. */
    4655typedef struct {
     56        /* Parenting hub */
     57        usb_hub_dev_t *hub;
     58        /** Guarding all fields */
     59        fibril_mutex_t guard;
     60        /** Current state of the port */
     61        port_state_t state;
     62        /** A speed of the device connected (if any). Valid unless state == PORT_DISABLED. */
     63        usb_speed_t speed;
    4764        /** Port number as reported in descriptors. */
    4865        unsigned int port_number;
    49         /** Device communication pipe. */
    50         usb_pipe_t *control_pipe;
    51         /** Mutex needed not only by CV for checking port reset. */
    52         fibril_mutex_t mutex;
    5366        /** CV for waiting to port reset completion. */
    54         fibril_condvar_t reset_cv;
    55         /** Port reset status.
    56          * Guarded by @c reset_mutex.
    57          */
    58         enum {
    59                 NO_RESET,
    60                 IN_RESET,
    61                 RESET_OK,
    62                 RESET_FAIL,
    63         } reset_status;
    64         /** Device reported to USB bus driver */
    65         bool device_attached;
     67        fibril_condvar_t state_cv;
    6668} usb_hub_port_t;
    6769
    68 /** Initialize hub port information.
    69  *
    70  * @param port Port to be initialized.
    71  */
    72 static inline void usb_hub_port_init(usb_hub_port_t *port,
    73     unsigned int port_number, usb_pipe_t *control_pipe)
    74 {
    75         assert(port);
    76         port->port_number = port_number;
    77         port->control_pipe = control_pipe;
    78         port->reset_status = NO_RESET;
    79         port->device_attached = false;
    80         fibril_mutex_initialize(&port->mutex);
    81         fibril_condvar_initialize(&port->reset_cv);
    82 }
     70void usb_hub_port_init(usb_hub_port_t *, usb_hub_dev_t *, unsigned int);
     71void usb_hub_port_fini(usb_hub_port_t *);
    8372
    84 int usb_hub_port_fini(usb_hub_port_t *port, usb_hub_dev_t *hub);
    85 int usb_hub_port_clear_feature(
    86     usb_hub_port_t *port, usb_hub_class_feature_t feature);
    87 int usb_hub_port_set_feature(
    88     usb_hub_port_t *port, usb_hub_class_feature_t feature);
    89 void usb_hub_port_reset_fail(usb_hub_port_t *port);
    9073void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_dev_t *hub);
    9174
Note: See TracChangeset for help on using the changeset viewer.