Ignore:
File:
1 edited

Legend:

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

    r9df965ec rf673f60  
    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(&port->hc_connection);
     143
     144        if (usb_address <= 0) {
     145                usb_log_error("Recieved invalid address(%d).\n", usb_address);
     146                return usb_address;
     147        }
     148        usb_log_debug("Sucessfully obtained address %d for port %d.\n",
     149            usb_address, port->number);
     150
     151        /* get default address */
     152        int ret = usb_hc_reserve_default_address(&port->hc_connection);
     153        if (ret != EOK) {
     154                usb_log_error("Failed to reserve default address on port %d.\n",
     155                    port->number);
     156                int ret2 = usb_hc_unregister_device(&port->hc_connection,
     157                    usb_address);
     158                if (ret2 != EOK) {
     159                        usb_log_fatal("Failed to return requested address on port %d.\n",
     160                           port->number);
     161                        return ret2;
     162                }
     163                usb_log_debug("Successfully returned reserved address on port %d.\n",
     164                        port->number);
     165                return ret;
     166        }
     167        usb_log_debug("Sucessfully obtained default address for port %d.\n",
     168            port->number);
    145169
    146170        /*
    147          * The host then waits for at least 100 ms to allow completion of
     171         * the host then waits for at least 100 ms to allow completion of
    148172         * an insertion process and for power at the device to become stable.
    149173         */
    150174        async_usleep(100000);
    151175
    152         /* Enable the port. */
     176        /* enable port */
    153177        uhci_port_set_enabled(port, true);
    154178
     
    172196        }
    173197
    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));
     198        /*
     199         * Initialize connection to the device.
     200         */
     201        /* FIXME: check for errors. */
     202        usb_device_connection_t new_dev_connection;
     203        usb_endpoint_pipe_t new_dev_ctrl_pipe;
     204        usb_device_connection_initialize_on_default_address(
     205            &new_dev_connection, &port->hc_connection);
     206        usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe,
     207            &new_dev_connection);
     208
     209        /*
     210         * Assign new address to the device. This function updates
     211         * the backing connection to still point to the same device.
     212         */
     213        /* FIXME: check for errors. */
     214        usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe);
     215        ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address);
     216        usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe);
     217
     218        if (ret != EOK) { /* address assigning went wrong */
     219                usb_log_error("Failed(%d) to assign address to the device.\n", ret);
    193220                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 
     221                int release = usb_hc_release_default_address(&port->hc_connection);
     222                if (release != EOK) {
     223                        usb_log_error("Failed to release default address on port %d.\n",
     224                            port->number);
     225                        return release;
     226                }
     227                usb_log_debug("Sucessfully released default address on port %d.\n",
     228                    port->number);
     229                return ret;
     230        }
     231        usb_log_debug("Sucessfully assigned address %d for port %d.\n",
     232            usb_address, port->number);
     233
     234        /* release default address */
     235        ret = usb_hc_release_default_address(&port->hc_connection);
     236        if (ret != EOK) {
     237                usb_log_error("Failed to release default address on port %d.\n",
     238                    port->number);
     239                return ret;
     240        }
     241        usb_log_debug("Sucessfully released default address on port %d.\n",
     242            port->number);
     243
     244        /* communicate and possibly report to devman */
     245        assert(port->attached_device == 0);
     246
     247        ret = usb_device_register_child_in_devman(new_dev_connection.address,
     248            new_dev_connection.hc_handle, port->rh, &port->attached_device);
     249
     250        if (ret != EOK) { /* something went wrong */
     251                usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret);
     252                uhci_port_set_enabled(port, false);
     253                return ENOMEM;
     254        }
     255        usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n",
     256                port->number, usb_address, port->attached_device);
     257
     258        /*
     259         * Register the device in the host controller.
     260         */
     261        usb_hc_attached_device_t new_device = {
     262                .address = new_dev_connection.address,
     263                .handle = port->attached_device
     264        };
     265
     266        ret = usb_hc_register_device(&port->hc_connection, &new_device);
     267        // TODO: proper error check here
     268        assert(ret == EOK);
     269
     270        return EOK;
     271}
    203272/*----------------------------------------------------------------------------*/
    204273static int uhci_port_remove_device(uhci_port_t *port)
Note: See TracChangeset for help on using the changeset viewer.