Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhub/usbhub.c

    r49ce810 rdd143621  
    7272static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info);
    7373
    74 static void usb_hub_polling_terminted_callback(usb_device_t * device,
     74static void usb_hub_polling_terminated_callback(usb_device_t * device,
    7575    bool was_error, void * data);
    7676
     
    200200        result->control_pipe = &usb_dev->ctrl_pipe;
    201201        result->is_default_address_used = false;
     202
     203        result->ports = NULL;
     204        result->port_count = (size_t) -1;
     205        fibril_mutex_initialize(&result->port_mutex);
     206
     207        fibril_mutex_initialize(&result->pending_ops_mutex);
     208        fibril_condvar_initialize(&result->pending_ops_cv);
     209        result->pending_ops_count = 0;
    202210        return result;
    203211}
     
    340348        rc = usb_device_auto_poll(hub_info->usb_device, 0,
    341349            hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1,
    342             usb_hub_polling_terminted_callback, hub_info);
     350            usb_hub_polling_terminated_callback, hub_info);
    343351        if (rc != EOK) {
    344352                usb_log_error("Failed to create polling fibril: %s.\n",
     
    473481 * @param data pointer to usb_hub_info_t structure
    474482 */
    475 static void usb_hub_polling_terminted_callback(usb_device_t * device,
     483static void usb_hub_polling_terminated_callback(usb_device_t * device,
    476484    bool was_error, void * data){
    477         usb_hub_info_t * hub_info = data;
    478         if(!hub_info) return;
    479         free(hub_info->ports);
    480         free(hub_info);
     485        usb_hub_info_t * hub = data;
     486        assert(hub);
     487
     488        fibril_mutex_lock(&hub->pending_ops_mutex);
     489
     490        /* The device is dead. However there might be some pending operations
     491         * that we need to wait for.
     492         * One of them is device adding in progress.
     493         * The respective fibril is probably waiting for status change
     494         * in port reset (port enable) callback.
     495         * Such change would never come (otherwise we would not be here).
     496         * Thus, we would flush all pending port resets.
     497         */
     498        if (hub->pending_ops_count > 0) {
     499                fibril_mutex_lock(&hub->port_mutex);
     500                size_t port;
     501                for (port = 0; port < hub->port_count; port++) {
     502                        usb_hub_port_t *the_port = hub->ports + port;
     503                        fibril_mutex_lock(&the_port->reset_mutex);
     504                        the_port->reset_completed = true;
     505                        the_port->reset_okay = false;
     506                        fibril_condvar_broadcast(&the_port->reset_cv);
     507                        fibril_mutex_unlock(&the_port->reset_mutex);
     508                }
     509                fibril_mutex_unlock(&hub->port_mutex);
     510        }
     511        /* And now wait for them. */
     512        while (hub->pending_ops_count > 0) {
     513                fibril_condvar_wait(&hub->pending_ops_cv,
     514                    &hub->pending_ops_mutex);
     515        }
     516        fibril_mutex_unlock(&hub->pending_ops_mutex);
     517
     518        free(hub->ports);
     519        free(hub);
    481520}
    482521
Note: See TracChangeset for help on using the changeset viewer.