Changeset 1d115c8 in mainline for uspace/drv/uhci-rhd/port.c


Ignore:
Timestamp:
2011-03-07T20:22:57Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5d5f971
Parents:
0969e45e (diff), ec4538d (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 development/ changes

File:
1 edited

Legend:

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

    r0969e45e r1d115c8  
    4646#include "port_status.h"
    4747
    48 static int uhci_port_new_device(uhci_port_t *port, uint16_t status);
     48static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
    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 new_device_enable_port(int portno, void *arg);
    53 
    54 int uhci_port_init(
    55   uhci_port_t *port, port_status_t *address, unsigned number,
    56   unsigned usec, ddf_dev_t *rh)
     52static 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 */
     65int uhci_port_init(uhci_port_t *port,
     66    port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh)
    5767{
    5868        assert(port);
     69
    5970        port->address = address;
    6071        port->number = number;
     
    6273        port->attached_device = 0;
    6374        port->rh = rh;
     75
    6476        int rc = usb_hc_connection_initialize_from_device(
    6577            &port->hc_connection, rh);
     
    7587                return ENOMEM;
    7688        }
     89
    7790        fibril_add_ready(port->checker);
    7891        usb_log_debug("Port(%p - %d): Added fibril. %x\n",
     
    8194}
    8295/*----------------------------------------------------------------------------*/
     96/** Finishes UHCI root hub port instance.
     97 *
     98 * @param[in] port Memory structure to use.
     99 *
     100 * Stops the polling fibril.
     101 */
    83102void uhci_port_fini(uhci_port_t *port)
    84103{
    85 // TODO: destroy fibril
    86 // TODO: hangup phone
    87 //      fibril_teardown(port->checker);
     104        /* TODO: Kill fibril here */
    88105        return;
    89106}
    90107/*----------------------------------------------------------------------------*/
     108/** Periodically checks port status and reports new devices.
     109 *
     110 * @param[in] port Memory structure to use.
     111 * @return Error code.
     112 */
    91113int uhci_port_check(void *port)
    92114{
    93         uhci_port_t *port_instance = port;
    94         assert(port_instance);
    95 //      port_status_write(port_instance->address, 0);
    96 
     115        uhci_port_t *instance = port;
     116        assert(instance);
     117
     118        /* Iteration count, for debug purposes only */
    97119        unsigned count = 0;
    98120
    99121        while (1) {
    100                 async_usleep(port_instance->wait_period_usec);
     122                async_usleep(instance->wait_period_usec);
    101123
    102124                /* read register value */
    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);
     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);
    108130                fibril_mutex_lock(&dbg_mtx);
    109131                usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n",
    110                   port_instance->address, port_instance->number, port_status, count++);
     132                  instance->address, instance->number, port_status, count++);
    111133//              print_port_status(port_status);
    112134                fibril_mutex_unlock(&dbg_mtx);
    113135
    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                         }
    150                 }
    151         }
    152         return EOK;
    153 }
    154 
     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;
     148                }
     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/*----------------------------------------------------------------------------*/
    155179/** Callback for enabling port during adding a new device.
    156180 *
     
    159183 * @return Error code.
    160184 */
    161 static int new_device_enable_port(int portno, void *arg)
     185int uhci_port_reset_enable(int portno, void *arg)
    162186{
    163187        uhci_port_t *port = (uhci_port_t *) arg;
     
    184208                port_status_write(port->address, port_status);
    185209                async_usleep(10000);
    186                 port_status =
    187                         port_status_read(port->address);
     210                port_status = port_status_read(port->address);
    188211                port_status &= ~STATUS_IN_RESET;
    189212                port_status_write(port->address, port_status);
     
    194217        /* Enable the port. */
    195218        uhci_port_set_enabled(port, true);
    196 
    197         return EOK;
    198 }
    199 
    200 /*----------------------------------------------------------------------------*/
    201 static int uhci_port_new_device(uhci_port_t *port, uint16_t status)
     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 */
     230int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed)
    202231{
    203232        assert(port);
     
    209238        usb_address_t dev_addr;
    210239        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    211             ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL,
    212             new_device_enable_port, port->number, port,
     240            speed, uhci_port_reset_enable, port->number, port,
    213241            &dev_addr, &port->attached_device, NULL, NULL, NULL);
    214242
    215243        if (rc != EOK) {
    216                 usb_log_error("Port(%p-%d): Failed(%d) adding new device: %s.\n",
     244                usb_log_error("Port(%p-%d): Failed(%d) to add device: %s.\n",
    217245                    port->address, port->number, rc, str_error(rc));
    218246                uhci_port_set_enabled(port, false);
     
    225253        return EOK;
    226254}
    227 
    228 /*----------------------------------------------------------------------------*/
    229 static int uhci_port_remove_device(uhci_port_t *port)
     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 */
     263int uhci_port_remove_device(uhci_port_t *port)
    230264{
    231265        usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n",
    232                 port->address, port->number, (unsigned int)port->attached_device);
    233 //      uhci_port_set_enabled(port, false);
    234         return EOK;
    235 }
    236 /*----------------------------------------------------------------------------*/
    237 static int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
     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 */
     275int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
    238276{
    239277        assert(port);
    240278
    241         /* read register value */
    242         port_status_t port_status
    243                 = port_status_read(port->address);
    244 
    245         /* enable port: register write */
     279        /* Read register value */
     280        port_status_t port_status = port_status_read(port->address);
     281
     282        /* Set enabled bit */
    246283        if (enabled) {
    247284                port_status |= STATUS_ENABLED;
     
    249286                port_status &= ~STATUS_ENABLED;
    250287        }
     288
     289        /* Write new value. */
    251290        port_status_write(port->address, port_status);
    252291
Note: See TracChangeset for help on using the changeset viewer.