Ignore:
File:
1 edited

Legend:

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

    r9df965ec r6427cf67  
    131131        return EOK;
    132132}
    133 
    134 /** Callback for enabling port during adding a new device.
    135  *
    136  * @param portno Port number (unused).
    137  * @param arg Pointer to uhci_port_t of port with the new device.
    138  * @return Error code.
    139  */
    140 static int new_device_enable_port(int portno, void *arg)
    141 {
    142         uhci_port_t *port = (uhci_port_t *) arg;
    143 
    144         usb_log_debug("new_device_enable_port(%d)\n", port->number);
     133/*----------------------------------------------------------------------------*/
     134static int uhci_port_new_device(uhci_port_t *port)
     135{
     136        assert(port);
     137        assert(usb_hc_connection_is_opened(&port->hc_connection));
     138
     139        usb_log_info("Adding new device on port %d.\n", port->number);
     140
     141        /* get address of the future device */
     142        const usb_address_t usb_address = usb_hc_request_address(
     143            &port->hc_connection, true);
     144
     145        if (usb_address <= 0) {
     146                usb_log_error("Recieved invalid address(%d).\n", usb_address);
     147                return usb_address;
     148        }
     149        usb_log_debug("Sucessfully obtained address %d for port %d.\n",
     150            usb_address, port->number);
     151
     152        /* get default address */
     153        int ret = usb_hc_reserve_default_address(&port->hc_connection, true);
     154        if (ret != EOK) {
     155                usb_log_error("Failed to reserve default address on port %d.\n",
     156                    port->number);
     157                int ret2 = usb_hc_unregister_device(&port->hc_connection,
     158                    usb_address);
     159                if (ret2 != EOK) {
     160                        usb_log_fatal("Failed to return requested address on port %d.\n",
     161                           port->number);
     162                        return ret2;
     163                }
     164                usb_log_debug("Successfully returned reserved address on port %d.\n",
     165                        port->number);
     166                return ret;
     167        }
     168        usb_log_debug("Sucessfully obtained default address for port %d.\n",
     169            port->number);
    145170
    146171        /*
    147          * The host then waits for at least 100 ms to allow completion of
     172         * the host then waits for at least 100 ms to allow completion of
    148173         * an insertion process and for power at the device to become stable.
    149174         */
    150175        async_usleep(100000);
    151176
    152         /* Enable the port. */
     177        /* enable port */
    153178        uhci_port_set_enabled(port, true);
    154179
     
    172197        }
    173198
    174         return EOK;
    175 }
    176 
    177 /*----------------------------------------------------------------------------*/
    178 static int uhci_port_new_device(uhci_port_t *port)
    179 {
    180         assert(port);
    181         assert(usb_hc_connection_is_opened(&port->hc_connection));
    182 
    183         usb_log_info("Detected new device on port %u.\n", port->number);
    184 
    185         usb_address_t dev_addr;
    186         int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    187             USB_SPEED_FULL,
    188             new_device_enable_port, port->number, port,
    189             &dev_addr, &port->attached_device);
    190         if (rc != EOK) {
    191                 usb_log_error("Failed adding new device on port %u: %s.\n",
    192                     port->number, str_error(rc));
     199        /*
     200         * Initialize connection to the device.
     201         */
     202        /* FIXME: check for errors. */
     203        usb_device_connection_t new_dev_connection;
     204        usb_endpoint_pipe_t new_dev_ctrl_pipe;
     205        usb_device_connection_initialize_on_default_address(
     206            &new_dev_connection, &port->hc_connection);
     207        usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe,
     208            &new_dev_connection);
     209
     210        /*
     211         * Assign new address to the device. This function updates
     212         * the backing connection to still point to the same device.
     213         */
     214        /* FIXME: check for errors. */
     215        usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe);
     216        ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address);
     217        usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe);
     218
     219        if (ret != EOK) { /* address assigning went wrong */
     220                usb_log_error("Failed(%d) to assign address to the device.\n", ret);
    193221                uhci_port_set_enabled(port, false);
    194                 return rc;
    195         }
    196 
    197         usb_log_info("New device on port %u has address %d (handle %zu).\n",
    198             port->number, dev_addr, port->attached_device);
    199 
    200         return EOK;
    201 }
    202 
     222                int release = usb_hc_release_default_address(&port->hc_connection);
     223                if (release != EOK) {
     224                        usb_log_error("Failed to release default address on port %d.\n",
     225                            port->number);
     226                        return release;
     227                }
     228                usb_log_debug("Sucessfully released default address on port %d.\n",
     229                    port->number);
     230                return ret;
     231        }
     232        usb_log_debug("Sucessfully assigned address %d for port %d.\n",
     233            usb_address, port->number);
     234
     235        /* release default address */
     236        ret = usb_hc_release_default_address(&port->hc_connection);
     237        if (ret != EOK) {
     238                usb_log_error("Failed to release default address on port %d.\n",
     239                    port->number);
     240                return ret;
     241        }
     242        usb_log_debug("Sucessfully released default address on port %d.\n",
     243            port->number);
     244
     245        /* communicate and possibly report to devman */
     246        assert(port->attached_device == 0);
     247
     248        ret = usb_device_register_child_in_devman(new_dev_connection.address,
     249            new_dev_connection.hc_handle, port->rh, &port->attached_device);
     250
     251        if (ret != EOK) { /* something went wrong */
     252                usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret);
     253                uhci_port_set_enabled(port, false);
     254                return ENOMEM;
     255        }
     256        usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n",
     257                port->number, usb_address, port->attached_device);
     258
     259        /*
     260         * Register the device in the host controller.
     261         */
     262        usb_hc_attached_device_t new_device = {
     263                .address = new_dev_connection.address,
     264                .handle = port->attached_device
     265        };
     266
     267        ret = usb_hc_register_device(&port->hc_connection, &new_device);
     268        // TODO: proper error check here
     269        assert(ret == EOK);
     270
     271        return EOK;
     272}
    203273/*----------------------------------------------------------------------------*/
    204274static int uhci_port_remove_device(uhci_port_t *port)
Note: See TracChangeset for help on using the changeset viewer.