Changeset 00aece0 in mainline for uspace/drv/bus/usb/uhcirh/port.c


Ignore:
Timestamp:
2012-02-18T16:47:38Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4449c6c
Parents:
bd5f3b7 (diff), f943dd3 (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 mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/uhcirh/port.c

    rbd5f3b7 r00aece0  
    3737#include <str_error.h>
    3838#include <async.h>
     39#include <devman.h>
    3940
    4041#include <usb/usb.h>    /* usb_address_t */
    41 #include <usb/dev/hub.h>    /* usb_hc_new_device_wrapper */
    4242#include <usb/debug.h>
    4343
    4444#include "port.h"
    4545
     46#define MAX_ERROR_COUNT 5
     47
    4648static int uhci_port_check(void *port);
    47 static int uhci_port_reset_enable(int portno, void *arg);
     49static int uhci_port_reset_enable(void *arg);
    4850static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
    4951static int uhci_port_remove_device(uhci_port_t *port);
     
    100102        port->number = number;
    101103        port->wait_period_usec = usec;
    102         port->attached_device = 0;
     104        port->attached_device.fun = NULL;
     105        port->attached_device.address = -1;
    103106        port->rh = rh;
    104107
     
    150153        assert(instance);
    151154
     155        unsigned allowed_failures = MAX_ERROR_COUNT;
     156#define CHECK_RET_FAIL(ret, msg...) \
     157        if (ret != EOK) { \
     158                usb_log_error(msg); \
     159                if (!(allowed_failures-- > 0)) { \
     160                        usb_log_fatal( \
     161                           "Maximum number of failures reached, " \
     162                           "bailing out.\n"); \
     163                        return ret; \
     164                } \
     165                continue; \
     166        } else (void)0
     167
    152168        while (1) {
    153169                async_usleep(instance->wait_period_usec);
     
    167183                    instance->id_string, port_status);
    168184
     185                int ret = usb_hc_connection_open(&instance->hc_connection);
     186                CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n",
     187                    instance->id_string, str_error(ret));
     188
    169189                /* Remove any old device */
    170                 if (instance->attached_device) {
    171                         usb_log_debug2("%s: Removing device.\n",
    172                             instance->id_string);
     190                if (instance->attached_device.fun) {
    173191                        uhci_port_remove_device(instance);
    174192                }
    175193
    176                 int ret =
    177                     usb_hc_connection_open(&instance->hc_connection);
    178                 if (ret != EOK) {
    179                         usb_log_error("%s: Failed to connect to HC.",
    180                             instance->id_string);
    181                         continue;
    182                 }
    183 
    184194                if ((port_status & STATUS_CONNECTED) != 0) {
    185                         /* New device */
     195                        /* New device, this will take care of WC bits */
    186196                        const usb_speed_t speed =
    187197                            ((port_status & STATUS_LOW_SPEED) != 0) ?
     
    196206
    197207                ret = usb_hc_connection_close(&instance->hc_connection);
    198                 if (ret != EOK) {
    199                         usb_log_error("%s: Failed to disconnect.",
    200                             instance->id_string);
    201                 }
     208                CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n",
     209                    instance->id_string, str_error(ret));
    202210        }
    203211        return EOK;
     
    212220 * Resets and enables the ub port.
    213221 */
    214 int uhci_port_reset_enable(int portno, void *arg)
     222int uhci_port_reset_enable(void *arg)
    215223{
    216224        uhci_port_t *port = arg;
     
    252260{
    253261        assert(port);
    254         assert(usb_hc_connection_is_opened(&port->hc_connection));
    255262
    256263        usb_log_debug("%s: Detected new device.\n", port->id_string);
    257264
    258         int ret, count = 0;
    259         usb_address_t dev_addr;
     265        int ret, count = MAX_ERROR_COUNT;
    260266        do {
    261267                ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    262                     speed, uhci_port_reset_enable, port->number, port,
    263                     &dev_addr, &port->attached_device, NULL, NULL, NULL);
    264         } while (ret != EOK && ++count < 4);
     268                    speed, uhci_port_reset_enable, port,
     269                    &port->attached_device.address, NULL, NULL,
     270                    &port->attached_device.fun);
     271        } while (ret != EOK && count-- > 0);
    265272
    266273        if (ret != EOK) {
     
    271278        }
    272279
    273         usb_log_info("New device at port %u, address %d (handle %" PRIun ").\n",
    274             port->number, dev_addr, port->attached_device);
     280        usb_log_info("%s: New device, address %d (handle %" PRIun ").\n",
     281            port->id_string, port->attached_device.address,
     282            port->attached_device.fun->handle);
    275283        return EOK;
    276284}
     
    278286/** Remove device.
    279287 *
    280  * @param[in] port Memory structure to use.
    281  * @return Error code.
    282  *
    283  * Does not work, DDF does not support device removal.
    284  * Does not even free used USB address (it would be dangerous if tis driver
    285  * is still running).
     288 * @param[in] port Port instance to use.
     289 * @return Error code.
    286290 */
    287291int uhci_port_remove_device(uhci_port_t *port)
    288292{
    289         usb_log_error("%s: Don't know how to remove device %" PRIun ".\n",
    290             port->id_string, port->attached_device);
    291         port->attached_device = 0;
    292         return ENOTSUP;
     293        assert(port);
     294        /* There is nothing to remove. */
     295        if (port->attached_device.fun == NULL) {
     296                usb_log_warning("%s: Removed a ghost device.\n",
     297                    port->id_string);
     298                assert(port->attached_device.address == -1);
     299                return EOK;
     300        }
     301
     302        usb_log_debug("%s: Removing device.\n", port->id_string);
     303
     304        /* Stop driver first */
     305        int ret = ddf_fun_unbind(port->attached_device.fun);
     306        if (ret != EOK) {
     307                usb_log_error("%s: Failed to remove child function: %s.\n",
     308                   port->id_string, str_error(ret));
     309                return ret;
     310        }
     311        ddf_fun_destroy(port->attached_device.fun);
     312        port->attached_device.fun = NULL;
     313
     314        /* Driver stopped, free used address */
     315        ret = usb_hub_unregister_device(&port->hc_connection,
     316            &port->attached_device);
     317        if (ret != EOK) {
     318                usb_log_error("%s: Failed to unregister address of removed "
     319                    "device: %s.\n", port->id_string, str_error(ret));
     320                return ret;
     321        }
     322        port->attached_device.address = -1;
     323
     324        usb_log_info("%s: Removed attached device.\n", port->id_string);
     325        return EOK;
    293326}
    294327/*----------------------------------------------------------------------------*/
Note: See TracChangeset for help on using the changeset viewer.