Ignore:
File:
1 edited

Legend:

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

    re231d26 r344a0ac  
    5050/** Information for fibril for device discovery. */
    5151struct add_device_phase1 {
    52         usb_hub_info_t *hub;
     52        usb_hub_dev_t *hub;
    5353        usb_hub_port_t *port;
    5454        usb_speed_t speed;
    5555};
    5656
    57 static void usb_hub_port_removed_device(usb_hub_port_t *port,
    58     usb_hub_info_t *hub);
     57static int usb_hub_port_device_gone(usb_hub_port_t *port, usb_hub_dev_t *hub);
    5958static void usb_hub_port_reset_completed(usb_hub_port_t *port,
    6059    usb_port_status_t status);
    6160static int get_port_status(usb_hub_port_t *port, usb_port_status_t *status);
    62 static int enable_port_callback(int port_no, void *arg);
     61static int enable_port_callback(void *arg);
    6362static int add_device_phase1_worker_fibril(void *arg);
    64 static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_info_t *hub,
     63static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_dev_t *hub,
    6564    usb_speed_t speed);
    6665
     66int usb_hub_port_fini(usb_hub_port_t *port, usb_hub_dev_t *hub)
     67{
     68        assert(port);
     69        if (port->attached_device.fun)
     70                return usb_hub_port_device_gone(port, hub);
     71        return EOK;
     72}
     73/*----------------------------------------------------------------------------*/
    6774/**
    6875 * Clear feature on hub port.
    6976 *
    70  * @param hc Host controller telephone
    71  * @param address Hub address
    72  * @param port_index Port
    73  * @param feature Feature selector
     77 * @param port Port structure.
     78 * @param feature Feature selector.
    7479 * @return Operation result
    7580 */
     
    7883{
    7984        assert(port);
    80         usb_device_request_setup_packet_t clear_request = {
     85        const usb_device_request_setup_packet_t clear_request = {
    8186                .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
    8287                .request = USB_DEVREQ_CLEAR_FEATURE,
     
    9095/*----------------------------------------------------------------------------*/
    9196/**
    92  * Clear feature on hub port.
    93  *
    94  * @param hc Host controller telephone
    95  * @param address Hub address
    96  * @param port_index Port
    97  * @param feature Feature selector
     97 * Set feature on hub port.
     98 *
     99 * @param port Port structure.
     100 * @param feature Feature selector.
    98101 * @return Operation result
    99102 */
     
    102105{
    103106        assert(port);
    104         usb_device_request_setup_packet_t clear_request = {
     107        const usb_device_request_setup_packet_t clear_request = {
    105108                .request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE,
    106109                .request = USB_DEVREQ_SET_FEATURE,
     
    113116}
    114117/*----------------------------------------------------------------------------*/
     118/**
     119 * Mark reset process as failed due to external reasons
     120 *
     121 * @param port Port structure
     122 */
    115123void usb_hub_port_reset_fail(usb_hub_port_t *port)
    116124{
     
    124132/*----------------------------------------------------------------------------*/
    125133/**
    126  * Process interrupts on given hub port
     134 * Process interrupts on given port
    127135 *
    128136 * Accepts connection, over current and port reset change.
     137 * @param port port structure
    129138 * @param hub hub representation
    130  * @param port port number, starting from 1
    131  */
    132 void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_info_t *hub)
     139 */
     140void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_dev_t *hub)
    133141{
    134142        assert(port);
     
    171179                         * to that handler, it shall ACK the change too. */
    172180                        if (!(status & USB_HUB_PORT_C_STATUS_ENABLED)) {
    173                                 usb_hub_port_removed_device(port, hub);
     181                                usb_hub_port_device_gone(port, hub);
    174182                        }
    175183                }
     
    180188                usb_log_info("Port %zu, disabled because of errors.\n",
    181189                   port->port_number);
    182                 usb_hub_port_removed_device(port, hub);
     190                usb_hub_port_device_gone(port, hub);
    183191                const int rc = usb_hub_port_clear_feature(port,
    184192                        USB_HUB_FEATURE_C_PORT_ENABLE);
     
    238246            port->port_number, status);
    239247}
    240 
     248/*----------------------------------------------------------------------------*/
    241249/**
    242250 * routine called when a device on port has been removed
     
    245253 * Otherwise does not do anything, because DDF does not allow to remove device
    246254 * from it`s device tree.
     255 * @param port port structure
    247256 * @param hub hub representation
    248  * @param port port number, starting from 1
    249  */
    250 static void usb_hub_port_removed_device(usb_hub_port_t *port,
    251     usb_hub_info_t *hub)
     257 */
     258int usb_hub_port_device_gone(usb_hub_port_t *port, usb_hub_dev_t *hub)
    252259{
    253260        assert(port);
    254261        assert(hub);
    255         if (port->attached_device.address >= 0) {
    256                 fibril_mutex_lock(&port->mutex);
    257                 port->attached_device.address = -1;
    258                 port->attached_device.handle = 0;
    259                 fibril_mutex_unlock(&port->mutex);
    260                 usb_log_info("Removed device on port %zu.\n",
    261                     port->port_number);
    262         } else {
     262        if (port->attached_device.address < 0) {
    263263                usb_log_warning(
    264264                    "Device on port %zu removed before being registered.\n",
     
    271271                 */
    272272                usb_hub_port_reset_fail(port);
    273         }
    274 }
    275 
     273                return EOK;
     274        }
     275
     276        fibril_mutex_lock(&port->mutex);
     277        assert(port->attached_device.fun);
     278        usb_log_debug("Removing device on port %zu.\n", port->port_number);
     279        int ret = ddf_fun_unbind(port->attached_device.fun);
     280        if (ret != EOK) {
     281                usb_log_error("Failed to unbind child function on port"
     282                    " %zu: %s.\n", port->port_number, str_error(ret));
     283                fibril_mutex_unlock(&port->mutex);
     284                return ret;
     285        }
     286
     287        ddf_fun_destroy(port->attached_device.fun);
     288        port->attached_device.fun = NULL;
     289
     290        ret = usb_hc_connection_open(&hub->connection);
     291        if (ret == EOK) {
     292                ret = usb_hc_unregister_device(&hub->connection,
     293                    port->attached_device.address);
     294                if (ret != EOK) {
     295                        usb_log_warning("Failed to unregister address of the "
     296                            "removed device: %s.\n", str_error(ret));
     297                }
     298                ret = usb_hc_connection_close(&hub->connection);
     299                if (ret != EOK) {
     300                        usb_log_warning("Failed to close hc connection %s.\n",
     301                            str_error(ret));
     302                }
     303
     304        } else {
     305                usb_log_warning("Failed to open hc connection %s.\n",
     306                    str_error(ret));
     307        }
     308
     309        port->attached_device.address = -1;
     310        fibril_mutex_unlock(&port->mutex);
     311        usb_log_info("Removed device on port %zu.\n", port->port_number);
     312        return EOK;
     313}
     314/*----------------------------------------------------------------------------*/
    276315/**
    277316 * Process port reset change
     
    279318 * After this change port should be enabled, unless some problem occurred.
    280319 * This functions triggers second phase of enabling new device.
    281  * @param hub
    282  * @param port
    283  * @param status
    284  */
    285 static void usb_hub_port_reset_completed(usb_hub_port_t *port,
     320 * @param port Port structure
     321 * @param status Port status mask
     322 */
     323void usb_hub_port_reset_completed(usb_hub_port_t *port,
    286324    usb_port_status_t status)
    287325{
     
    313351/** Retrieve port status.
    314352 *
    315  * @param[in] ctrl_pipe Control pipe to use.
    316  * @param[in] port Port number (starting at 1).
     353 * @param[in] port Port structure
    317354 * @param[out] status Where to store the port status.
    318355 * @return Error code.
     
    358395 *
    359396 * @param port_no Port number (starting at 1).
    360  * @param arg Custom argument, points to @c usb_hub_info_t.
     397 * @param arg Custom argument, points to @c usb_hub_dev_t.
    361398 * @return Error code.
    362399 */
    363 static int enable_port_callback(int port_no, void *arg)
     400static int enable_port_callback(void *arg)
    364401{
    365402        usb_hub_port_t *port = arg;
     
    380417        fibril_mutex_unlock(&port->mutex);
    381418
    382         if (port->reset_okay) {
    383                 return EOK;
    384         } else {
    385                 return ESTALL;
    386         }
    387 }
    388 
     419        return port->reset_okay ? EOK : ESTALL;
     420}
     421/*----------------------------------------------------------------------------*/
    389422/** Fibril for adding a new device.
    390423 *
     
    395428 * @return 0 Always.
    396429 */
    397 static int add_device_phase1_worker_fibril(void *arg)
     430int add_device_phase1_worker_fibril(void *arg)
    398431{
    399432        struct add_device_phase1 *data = arg;
     
    401434
    402435        usb_address_t new_address;
    403         devman_handle_t child_handle;
     436        ddf_fun_t *child_fun;
    404437
    405438        const int rc = usb_hc_new_device_wrapper(data->hub->usb_device->ddf_dev,
    406             &data->hub->connection, data->speed,
    407             enable_port_callback, (int) data->port->port_number,
    408             data->port, &new_address, &child_handle,
    409             NULL, NULL, NULL);
     439            &data->hub->connection, data->speed, enable_port_callback,
     440            data->port, &new_address, NULL, NULL, &child_fun);
    410441
    411442        if (rc != EOK) {
     
    416447
    417448        fibril_mutex_lock(&data->port->mutex);
    418         data->port->attached_device.handle = child_handle;
     449        data->port->attached_device.fun = child_fun;
    419450        data->port->attached_device.address = new_address;
    420451        fibril_mutex_unlock(&data->port->mutex);
     
    423454            "address %d (handle %" PRIun ").\n",
    424455            data->hub->usb_device->ddf_dev->name, data->port->port_number,
    425             new_address, child_handle);
     456            new_address, child_fun->handle);
    426457
    427458leave:
     
    434465        free(arg);
    435466
    436         return EOK;
    437 }
    438 
     467        return rc;
     468}
     469/*----------------------------------------------------------------------------*/
    439470/** Start device adding when connection change is detected.
    440471 *
     
    446477 * @return Error code.
    447478 */
    448 static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_info_t *hub,
     479static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_dev_t *hub,
    449480    usb_speed_t speed)
    450481{
     
    452483        assert(port);
    453484        struct add_device_phase1 *data
    454             = malloc(sizeof (struct add_device_phase1));
     485            = malloc(sizeof(struct add_device_phase1));
    455486        if (data == NULL) {
    456487                return ENOMEM;
Note: See TracChangeset for help on using the changeset viewer.