Changeset 3fb5a3e in mainline


Ignore:
Timestamp:
2011-05-28T14:34:43Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
af6136d
Parents:
400735e
Message:

Do not delete hub info too early

When a hub is disconnected during port change (device adding) the
structure was deleted and accessed *later* from the device adding
routine. Because allocator is next fit, the error went unnoticed.

Location:
uspace/drv/usbhub
Files:
3 edited

Legend:

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

    r400735e r3fb5a3e  
    407407        free(arg);
    408408
     409        fibril_mutex_lock(&data->hub->pending_ops_mutex);
     410        assert(data->hub->pending_ops_count > 0);
     411        data->hub->pending_ops_count--;
     412        fibril_condvar_signal(&data->hub->pending_ops_cv);
     413        fibril_mutex_unlock(&data->hub->pending_ops_mutex);
     414
     415
    409416        return EOK;
    410417}
     
    452459                return ENOMEM;
    453460        }
     461        fibril_mutex_lock(&hub->pending_ops_mutex);
     462        hub->pending_ops_count++;
     463        fibril_mutex_unlock(&hub->pending_ops_mutex);
    454464        fibril_add_ready(fibril);
    455465
  • uspace/drv/usbhub/usbhub.c

    r400735e r3fb5a3e  
    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        fibril_mutex_initialize(&result->pending_ops_mutex);
     204        fibril_condvar_initialize(&result->pending_ops_cv);
     205        result->pending_ops_count = 0;
    202206        return result;
    203207}
     
    340344        rc = usb_device_auto_poll(hub_info->usb_device, 0,
    341345            hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1,
    342             usb_hub_polling_terminted_callback, hub_info);
     346            usb_hub_polling_terminated_callback, hub_info);
    343347        if (rc != EOK) {
    344348                usb_log_error("Failed to create polling fibril: %s.\n",
     
    473477 * @param data pointer to usb_hub_info_t structure
    474478 */
    475 static void usb_hub_polling_terminted_callback(usb_device_t * device,
     479static void usb_hub_polling_terminated_callback(usb_device_t * device,
    476480    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);
     481        usb_hub_info_t * hub = data;
     482        assert(hub);
     483
     484        fibril_mutex_lock(&hub->pending_ops_mutex);
     485        while (hub->pending_ops_count > 0) {
     486                fibril_condvar_wait(&hub->pending_ops_cv,
     487                    &hub->pending_ops_mutex);
     488        }
     489        fibril_mutex_unlock(&hub->pending_ops_mutex);
     490
     491        free(hub->ports);
     492        free(hub);
    481493}
    482494
  • uspace/drv/usbhub/usbhub.h

    r400735e r3fb5a3e  
    8989        /** generic usb device data*/
    9090        usb_device_t * usb_device;
     91
     92        /** Number of pending operations on the mutex to prevent shooting
     93         * ourselves in the foot.
     94         * When the hub is disconnected but we are in the middle of some
     95         * operation, we cannot destroy this structure right away because
     96         * the pending operation might use it.
     97         */
     98        size_t pending_ops_count;
     99        /** Guard for pending_ops_count. */
     100        fibril_mutex_t pending_ops_mutex;
     101        /** Condition variable for pending_ops_count. */
     102        fibril_condvar_t pending_ops_cv;
     103
    91104};
    92105
Note: See TracChangeset for help on using the changeset viewer.