Ignore:
File:
1 edited

Legend:

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

    r344a0ac re231d26  
    5050/** Information for fibril for device discovery. */
    5151struct add_device_phase1 {
    52         usb_hub_dev_t *hub;
     52        usb_hub_info_t *hub;
    5353        usb_hub_port_t *port;
    5454        usb_speed_t speed;
    5555};
    5656
    57 static int usb_hub_port_device_gone(usb_hub_port_t *port, usb_hub_dev_t *hub);
     57static void usb_hub_port_removed_device(usb_hub_port_t *port,
     58    usb_hub_info_t *hub);
    5859static void usb_hub_port_reset_completed(usb_hub_port_t *port,
    5960    usb_port_status_t status);
    6061static int get_port_status(usb_hub_port_t *port, usb_port_status_t *status);
    61 static int enable_port_callback(void *arg);
     62static int enable_port_callback(int port_no, void *arg);
    6263static int add_device_phase1_worker_fibril(void *arg);
    63 static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_dev_t *hub,
     64static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_info_t *hub,
    6465    usb_speed_t speed);
    6566
    66 int 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 /*----------------------------------------------------------------------------*/
    7467/**
    7568 * Clear feature on hub port.
    7669 *
    77  * @param port Port structure.
    78  * @param feature Feature selector.
     70 * @param hc Host controller telephone
     71 * @param address Hub address
     72 * @param port_index Port
     73 * @param feature Feature selector
    7974 * @return Operation result
    8075 */
     
    8378{
    8479        assert(port);
    85         const usb_device_request_setup_packet_t clear_request = {
     80        usb_device_request_setup_packet_t clear_request = {
    8681                .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
    8782                .request = USB_DEVREQ_CLEAR_FEATURE,
     
    9590/*----------------------------------------------------------------------------*/
    9691/**
    97  * Set feature on hub port.
    98  *
    99  * @param port Port structure.
    100  * @param feature Feature selector.
     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
    10198 * @return Operation result
    10299 */
     
    105102{
    106103        assert(port);
    107         const usb_device_request_setup_packet_t clear_request = {
     104        usb_device_request_setup_packet_t clear_request = {
    108105                .request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE,
    109106                .request = USB_DEVREQ_SET_FEATURE,
     
    116113}
    117114/*----------------------------------------------------------------------------*/
    118 /**
    119  * Mark reset process as failed due to external reasons
    120  *
    121  * @param port Port structure
    122  */
    123115void usb_hub_port_reset_fail(usb_hub_port_t *port)
    124116{
     
    132124/*----------------------------------------------------------------------------*/
    133125/**
    134  * Process interrupts on given port
     126 * Process interrupts on given hub port
    135127 *
    136128 * Accepts connection, over current and port reset change.
    137  * @param port port structure
    138129 * @param hub hub representation
    139  */
    140 void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_dev_t *hub)
     130 * @param port port number, starting from 1
     131 */
     132void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_info_t *hub)
    141133{
    142134        assert(port);
     
    179171                         * to that handler, it shall ACK the change too. */
    180172                        if (!(status & USB_HUB_PORT_C_STATUS_ENABLED)) {
    181                                 usb_hub_port_device_gone(port, hub);
     173                                usb_hub_port_removed_device(port, hub);
    182174                        }
    183175                }
     
    188180                usb_log_info("Port %zu, disabled because of errors.\n",
    189181                   port->port_number);
    190                 usb_hub_port_device_gone(port, hub);
     182                usb_hub_port_removed_device(port, hub);
    191183                const int rc = usb_hub_port_clear_feature(port,
    192184                        USB_HUB_FEATURE_C_PORT_ENABLE);
     
    246238            port->port_number, status);
    247239}
    248 /*----------------------------------------------------------------------------*/
     240
    249241/**
    250242 * routine called when a device on port has been removed
     
    253245 * Otherwise does not do anything, because DDF does not allow to remove device
    254246 * from it`s device tree.
    255  * @param port port structure
    256247 * @param hub hub representation
    257  */
    258 int usb_hub_port_device_gone(usb_hub_port_t *port, usb_hub_dev_t *hub)
     248 * @param port port number, starting from 1
     249 */
     250static void usb_hub_port_removed_device(usb_hub_port_t *port,
     251    usb_hub_info_t *hub)
    259252{
    260253        assert(port);
    261254        assert(hub);
    262         if (port->attached_device.address < 0) {
     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 {
    263263                usb_log_warning(
    264264                    "Device on port %zu removed before being registered.\n",
     
    271271                 */
    272272                usb_hub_port_reset_fail(port);
    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 /*----------------------------------------------------------------------------*/
     273        }
     274}
     275
    315276/**
    316277 * Process port reset change
     
    318279 * After this change port should be enabled, unless some problem occurred.
    319280 * This functions triggers second phase of enabling new device.
    320  * @param port Port structure
    321  * @param status Port status mask
    322  */
    323 void usb_hub_port_reset_completed(usb_hub_port_t *port,
     281 * @param hub
     282 * @param port
     283 * @param status
     284 */
     285static void usb_hub_port_reset_completed(usb_hub_port_t *port,
    324286    usb_port_status_t status)
    325287{
     
    351313/** Retrieve port status.
    352314 *
    353  * @param[in] port Port structure
     315 * @param[in] ctrl_pipe Control pipe to use.
     316 * @param[in] port Port number (starting at 1).
    354317 * @param[out] status Where to store the port status.
    355318 * @return Error code.
     
    395358 *
    396359 * @param port_no Port number (starting at 1).
    397  * @param arg Custom argument, points to @c usb_hub_dev_t.
     360 * @param arg Custom argument, points to @c usb_hub_info_t.
    398361 * @return Error code.
    399362 */
    400 static int enable_port_callback(void *arg)
     363static int enable_port_callback(int port_no, void *arg)
    401364{
    402365        usb_hub_port_t *port = arg;
     
    417380        fibril_mutex_unlock(&port->mutex);
    418381
    419         return port->reset_okay ? EOK : ESTALL;
    420 }
    421 /*----------------------------------------------------------------------------*/
     382        if (port->reset_okay) {
     383                return EOK;
     384        } else {
     385                return ESTALL;
     386        }
     387}
     388
    422389/** Fibril for adding a new device.
    423390 *
     
    428395 * @return 0 Always.
    429396 */
    430 int add_device_phase1_worker_fibril(void *arg)
     397static int add_device_phase1_worker_fibril(void *arg)
    431398{
    432399        struct add_device_phase1 *data = arg;
     
    434401
    435402        usb_address_t new_address;
    436         ddf_fun_t *child_fun;
     403        devman_handle_t child_handle;
    437404
    438405        const int rc = usb_hc_new_device_wrapper(data->hub->usb_device->ddf_dev,
    439             &data->hub->connection, data->speed, enable_port_callback,
    440             data->port, &new_address, NULL, NULL, &child_fun);
     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);
    441410
    442411        if (rc != EOK) {
     
    447416
    448417        fibril_mutex_lock(&data->port->mutex);
    449         data->port->attached_device.fun = child_fun;
     418        data->port->attached_device.handle = child_handle;
    450419        data->port->attached_device.address = new_address;
    451420        fibril_mutex_unlock(&data->port->mutex);
     
    454423            "address %d (handle %" PRIun ").\n",
    455424            data->hub->usb_device->ddf_dev->name, data->port->port_number,
    456             new_address, child_fun->handle);
     425            new_address, child_handle);
    457426
    458427leave:
     
    465434        free(arg);
    466435
    467         return rc;
    468 }
    469 /*----------------------------------------------------------------------------*/
     436        return EOK;
     437}
     438
    470439/** Start device adding when connection change is detected.
    471440 *
     
    477446 * @return Error code.
    478447 */
    479 static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_dev_t *hub,
     448static int create_add_device_fibril(usb_hub_port_t *port, usb_hub_info_t *hub,
    480449    usb_speed_t speed)
    481450{
     
    483452        assert(port);
    484453        struct add_device_phase1 *data
    485             = malloc(sizeof(struct add_device_phase1));
     454            = malloc(sizeof (struct add_device_phase1));
    486455        if (data == NULL) {
    487456                return ENOMEM;
Note: See TracChangeset for help on using the changeset viewer.