Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-rhd/port.c

    r275bf456 rdced52a  
    4646#include "port_status.h"
    4747
    48 static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
     48static int uhci_port_new_device(uhci_port_t *port, uint16_t status);
    4949static int uhci_port_remove_device(uhci_port_t *port);
    5050static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
    5151static int uhci_port_check(void *port);
    52 static int uhci_port_reset_enable(int portno, void *arg);
    53 /*----------------------------------------------------------------------------*/
    54 /** Initializes UHCI root hub port instance.
    55  *
    56  * @param[in] port Memory structure to use.
    57  * @param[in] addr Address of I/O register.
    58  * @param[in] number Port number.
    59  * @param[in] usec Polling interval.
    60  * @param[in] rh Pointer to ddf instance fo the root hub driver.
    61  * @return Error code.
    62  *
    63  * Starts the polling fibril.
    64  */
    65 int uhci_port_init(uhci_port_t *port,
    66     port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh)
     52static int new_device_enable_port(int portno, void *arg);
     53
     54int uhci_port_init(
     55  uhci_port_t *port, port_status_t *address, unsigned number,
     56  unsigned usec, ddf_dev_t *rh)
    6757{
    6858        assert(port);
    69 
    7059        port->address = address;
    7160        port->number = number;
     
    7362        port->attached_device = 0;
    7463        port->rh = rh;
    75 
    7664        int rc = usb_hc_connection_initialize_from_device(
    7765            &port->hc_connection, rh);
     
    8775                return ENOMEM;
    8876        }
    89 
    9077        fibril_add_ready(port->checker);
    9178        usb_log_debug("Port(%p - %d): Added fibril. %x\n",
     
    9481}
    9582/*----------------------------------------------------------------------------*/
    96 /** Finishes UHCI root hub port instance.
    97  *
    98  * @param[in] port Memory structure to use.
    99  *
    100  * Stops the polling fibril.
    101  */
    10283void uhci_port_fini(uhci_port_t *port)
    10384{
    104         /* TODO: Kill fibril here */
     85// TODO: destroy fibril
     86// TODO: hangup phone
     87//      fibril_teardown(port->checker);
    10588        return;
    10689}
    10790/*----------------------------------------------------------------------------*/
    108 /** Periodically checks port status and reports new devices.
    109  *
    110  * @param[in] port Memory structure to use.
    111  * @return Error code.
    112  */
    11391int uhci_port_check(void *port)
    11492{
    115         uhci_port_t *instance = port;
    116         assert(instance);
    117 
    118         /* Iteration count, for debug purposes only */
     93        uhci_port_t *port_instance = port;
     94        assert(port_instance);
     95//      port_status_write(port_instance->address, 0);
     96
    11997        unsigned count = 0;
    12098
    12199        while (1) {
    122                 async_usleep(instance->wait_period_usec);
     100                async_usleep(port_instance->wait_period_usec);
    123101
    124102                /* read register value */
    125                 port_status_t port_status = port_status_read(instance->address);
    126 
    127                 /* debug print mutex */
    128                 static fibril_mutex_t dbg_mtx =
    129                     FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
     103                port_status_t port_status =
     104                        port_status_read(port_instance->address);
     105
     106                /* debug print */
     107                static fibril_mutex_t dbg_mtx = FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
    130108                fibril_mutex_lock(&dbg_mtx);
    131109                usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n",
    132                   instance->address, instance->number, port_status, count++);
     110                  port_instance->address, port_instance->number, port_status, count++);
    133111//              print_port_status(port_status);
    134112                fibril_mutex_unlock(&dbg_mtx);
    135113
    136                 if ((port_status & STATUS_CONNECTED_CHANGED) == 0)
    137                         continue;
    138 
    139                 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
    140                     instance->address, instance->number, port_status);
    141 
    142                 int rc =
    143                     usb_hc_connection_open(&instance->hc_connection);
    144                 if (rc != EOK) {
    145                         usb_log_error("Port(%p - %d): Failed to connect to HC.",
    146                             instance->address, instance->number);
    147                         continue;
     114                if ((port_status & STATUS_CONNECTED_CHANGED) != 0) {
     115                        usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
     116                            port_instance->address, port_instance->number, port_status);
     117
     118
     119                        int rc = usb_hc_connection_open(
     120                            &port_instance->hc_connection);
     121                        if (rc != EOK) {
     122                                usb_log_error("Port(%p - %d): Failed to connect to HC.",
     123                                    port_instance->address, port_instance->number);
     124                                continue;
     125                        }
     126
     127                        /* remove any old device */
     128                        if (port_instance->attached_device) {
     129                                usb_log_debug("Port(%p - %d): Removing device.\n",
     130                                    port_instance->address, port_instance->number);
     131                                uhci_port_remove_device(port_instance);
     132                        }
     133
     134                        if ((port_status & STATUS_CONNECTED) != 0) {
     135                                /* new device */
     136                                uhci_port_new_device(port_instance, port_status);
     137                        } else {
     138                                /* ack changes by writing one to WC bits */
     139                                port_status_write(port_instance->address, port_status);
     140                                usb_log_debug("Port(%p - %d): Change status ACK.\n",
     141                                                port_instance->address, port_instance->number);
     142                        }
     143
     144                        rc = usb_hc_connection_close(
     145                            &port_instance->hc_connection);
     146                        if (rc != EOK) {
     147                                usb_log_error("Port(%p - %d): Failed to disconnect from HC.",
     148                                    port_instance->address, port_instance->number);
     149                        }
    148150                }
    149 
    150                 /* Remove any old device */
    151                 if (instance->attached_device) {
    152                         usb_log_debug2("Port(%p - %d): Removing device.\n",
    153                             instance->address, instance->number);
    154                         uhci_port_remove_device(instance);
    155                 }
    156 
    157                 if ((port_status & STATUS_CONNECTED) != 0) {
    158                         /* New device */
    159                         const usb_speed_t speed =
    160                             ((port_status & STATUS_LOW_SPEED) != 0) ?
    161                             USB_SPEED_LOW : USB_SPEED_FULL;
    162                         uhci_port_new_device(instance, speed);
    163                 } else {
    164                         /* Write one to WC bits, to ack changes */
    165                         port_status_write(instance->address, port_status);
    166                         usb_log_debug("Port(%p - %d): Change status ACK.\n",
    167                             instance->address, instance->number);
    168                 }
    169 
    170                 rc = usb_hc_connection_close(&instance->hc_connection);
    171                 if (rc != EOK) {
    172                         usb_log_error("Port(%p - %d): Failed to disconnect.",
    173                             instance->address, instance->number);
    174                 }
    175         }
    176         return EOK;
    177 }
    178 /*----------------------------------------------------------------------------*/
     151        }
     152        return EOK;
     153}
     154
    179155/** Callback for enabling port during adding a new device.
    180156 *
     
    183159 * @return Error code.
    184160 */
    185 int uhci_port_reset_enable(int portno, void *arg)
     161static int new_device_enable_port(int portno, void *arg)
    186162{
    187163        uhci_port_t *port = (uhci_port_t *) arg;
     
    208184                port_status_write(port->address, port_status);
    209185                async_usleep(10000);
    210                 port_status = port_status_read(port->address);
     186                port_status =
     187                        port_status_read(port->address);
    211188                port_status &= ~STATUS_IN_RESET;
    212189                port_status_write(port->address, port_status);
     
    217194        /* Enable the port. */
    218195        uhci_port_set_enabled(port, true);
    219         return EOK;
    220 }
    221 /*----------------------------------------------------------------------------*/
    222 /** Initializes and reports connected device.
    223  *
    224  * @param[in] port Memory structure to use.
    225  * @param[in] speed Detected speed.
    226  * @return Error code.
    227  *
    228  * Uses libUSB function to do the actual work.
    229  */
    230 int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed)
     196
     197        return EOK;
     198}
     199
     200/*----------------------------------------------------------------------------*/
     201static int uhci_port_new_device(uhci_port_t *port, uint16_t status)
    231202{
    232203        assert(port);
     
    238209        usb_address_t dev_addr;
    239210        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    240             speed, uhci_port_reset_enable, port->number, port,
     211            ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL,
     212            new_device_enable_port, port->number, port,
    241213            &dev_addr, &port->attached_device, NULL, NULL, NULL);
    242214
    243215        if (rc != EOK) {
    244                 usb_log_error("Port(%p-%d): Failed(%d) to add device: %s.\n",
     216                usb_log_error("Port(%p-%d): Failed(%d) adding new device: %s.\n",
    245217                    port->address, port->number, rc, str_error(rc));
    246218                uhci_port_set_enabled(port, false);
     
    253225        return EOK;
    254226}
    255 /*----------------------------------------------------------------------------*/
    256 /** Removes device.
    257  *
    258  * @param[in] port Memory structure to use.
    259  * @return Error code.
    260  *
    261  * Does not work DDF does not support device removal.
    262  */
    263 int uhci_port_remove_device(uhci_port_t *port)
     227
     228/*----------------------------------------------------------------------------*/
     229static int uhci_port_remove_device(uhci_port_t *port)
    264230{
    265231        usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n",
    266             port->address, port->number, (unsigned int)port->attached_device);
    267         return EOK;
    268 }
    269 /*----------------------------------------------------------------------------*/
    270 /** Enables and disables port.
    271  *
    272  * @param[in] port Memory structure to use.
    273  * @return Error code. (Always EOK)
    274  */
    275 int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
     232                port->address, port->number, (unsigned int)port->attached_device);
     233//      uhci_port_set_enabled(port, false);
     234        return EOK;
     235}
     236/*----------------------------------------------------------------------------*/
     237static int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
    276238{
    277239        assert(port);
    278240
    279         /* Read register value */
    280         port_status_t port_status = port_status_read(port->address);
    281 
    282         /* Set enabled bit */
     241        /* read register value */
     242        port_status_t port_status
     243                = port_status_read(port->address);
     244
     245        /* enable port: register write */
    283246        if (enabled) {
    284247                port_status |= STATUS_ENABLED;
     
    286249                port_status &= ~STATUS_ENABLED;
    287250        }
    288 
    289         /* Write new value. */
    290251        port_status_write(port->address, port_status);
    291252
Note: See TracChangeset for help on using the changeset viewer.