Ignore:
File:
1 edited

Legend:

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

    r612af1a0 r5203e256  
    3737#include <str_error.h>
    3838#include <async.h>
    39 #include <devman.h>
    4039
    4140#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 
    4846static int uhci_port_check(void *port);
    49 static int uhci_port_reset_enable(void *arg);
     47static int uhci_port_reset_enable(int portno, void *arg);
    5048static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
    5149static int uhci_port_remove_device(uhci_port_t *port);
     
    102100        port->number = number;
    103101        port->wait_period_usec = usec;
    104         port->attached_device.fun = NULL;
    105         port->attached_device.address = -1;
     102        port->attached_device = 0;
    106103        port->rh = rh;
    107104
     
    153150        assert(instance);
    154151
    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 
    168152        while (1) {
    169153                async_usleep(instance->wait_period_usec);
     
    183167                    instance->id_string, port_status);
    184168
    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 
    189169                /* Remove any old device */
    190                 if (instance->attached_device.fun) {
     170                if (instance->attached_device) {
     171                        usb_log_debug2("%s: Removing device.\n",
     172                            instance->id_string);
    191173                        uhci_port_remove_device(instance);
    192174                }
    193175
     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
    194184                if ((port_status & STATUS_CONNECTED) != 0) {
    195                         /* New device, this will take care of WC bits */
     185                        /* New device */
    196186                        const usb_speed_t speed =
    197187                            ((port_status & STATUS_LOW_SPEED) != 0) ?
     
    206196
    207197                ret = usb_hc_connection_close(&instance->hc_connection);
    208                 CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n",
    209                     instance->id_string, str_error(ret));
     198                if (ret != EOK) {
     199                        usb_log_error("%s: Failed to disconnect.",
     200                            instance->id_string);
     201                }
    210202        }
    211203        return EOK;
     
    220212 * Resets and enables the ub port.
    221213 */
    222 int uhci_port_reset_enable(void *arg)
     214int uhci_port_reset_enable(int portno, void *arg)
    223215{
    224216        uhci_port_t *port = arg;
     
    264256        usb_log_debug("%s: Detected new device.\n", port->id_string);
    265257
    266         int ret, count = MAX_ERROR_COUNT;
     258        int ret, count = 0;
     259        usb_address_t dev_addr;
    267260        do {
    268261                ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    269                     speed, uhci_port_reset_enable, port,
    270                     &port->attached_device.address, NULL, NULL,
    271                     &port->attached_device.fun);
    272         } while (ret != EOK && count-- > 0);
     262                    speed, uhci_port_reset_enable, port->number, port,
     263                    &dev_addr, &port->attached_device, NULL, NULL, NULL);
     264        } while (ret != EOK && ++count < 4);
    273265
    274266        if (ret != EOK) {
     
    279271        }
    280272
    281         usb_log_info("%s: New device, address %d (handle %" PRIun ").\n",
    282             port->id_string, port->attached_device.address,
    283             port->attached_device.fun->handle);
     273        usb_log_info("New device at port %u, address %d (handle %" PRIun ").\n",
     274            port->number, dev_addr, port->attached_device);
    284275        return EOK;
    285276}
     
    287278/** Remove device.
    288279 *
    289  * @param[in] port Port instance to use.
    290  * @return Error code.
     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).
    291286 */
    292287int uhci_port_remove_device(uhci_port_t *port)
    293288{
    294         assert(port);
    295         /* There is nothing to remove. */
    296         if (port->attached_device.fun == NULL) {
    297                 usb_log_warning("%s: Removed a ghost device.\n",
    298                     port->id_string);
    299                 assert(port->attached_device.address == -1);
    300                 return EOK;
    301         }
    302 
    303         usb_log_debug("%s: Removing device.\n", port->id_string);
    304 
    305         /* Stop driver first */
    306         int ret = ddf_fun_unbind(port->attached_device.fun);
    307         if (ret != EOK) {
    308                 usb_log_error("%s: Failed to remove child function: %s.\n",
    309                    port->id_string, str_error(ret));
    310                 return ret;
    311         }
    312         ddf_fun_destroy(port->attached_device.fun);
    313         port->attached_device.fun = NULL;
    314 
    315         /* Driver stopped, free used address */
    316         ret = usb_hc_unregister_device(&port->hc_connection,
    317             port->attached_device.address);
    318         if (ret != EOK) {
    319                 usb_log_error("%s: Failed to unregister address of removed "
    320                     "device: %s.\n", port->id_string, str_error(ret));
    321                 return ret;
    322         }
    323         port->attached_device.address = -1;
    324 
    325         usb_log_info("%s: Removed attached device.\n", port->id_string);
    326         return EOK;
     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;
    327293}
    328294/*----------------------------------------------------------------------------*/
Note: See TracChangeset for help on using the changeset viewer.