diff options
-rw-r--r-- | drivers/ide/ide.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 287a66201150..16890769dca6 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -973,8 +973,8 @@ ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name) | |||
973 | * @drive: drive | 973 | * @drive: drive |
974 | * | 974 | * |
975 | * Automatically remove all the driver specific settings for this | 975 | * Automatically remove all the driver specific settings for this |
976 | * drive. This function may sleep and must not be called from IRQ | 976 | * drive. This function may not be called from IRQ context. The |
977 | * context. The caller must hold ide_setting_sem. | 977 | * caller must hold ide_setting_sem. |
978 | */ | 978 | */ |
979 | 979 | ||
980 | static void auto_remove_settings (ide_drive_t *drive) | 980 | static void auto_remove_settings (ide_drive_t *drive) |
@@ -1874,11 +1874,22 @@ void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) | |||
1874 | { | 1874 | { |
1875 | unsigned long flags; | 1875 | unsigned long flags; |
1876 | 1876 | ||
1877 | down(&ide_setting_sem); | ||
1878 | spin_lock_irqsave(&ide_lock, flags); | ||
1879 | #ifdef CONFIG_PROC_FS | 1877 | #ifdef CONFIG_PROC_FS |
1880 | ide_remove_proc_entries(drive->proc, driver->proc); | 1878 | ide_remove_proc_entries(drive->proc, driver->proc); |
1881 | #endif | 1879 | #endif |
1880 | down(&ide_setting_sem); | ||
1881 | spin_lock_irqsave(&ide_lock, flags); | ||
1882 | /* | ||
1883 | * ide_setting_sem protects the settings list | ||
1884 | * ide_lock protects the use of settings | ||
1885 | * | ||
1886 | * so we need to hold both, ide_settings_sem because we want to | ||
1887 | * modify the settings list, and ide_lock because we cannot take | ||
1888 | * a setting out that is being used. | ||
1889 | * | ||
1890 | * OTOH both ide_{read,write}_setting are only ever used under | ||
1891 | * ide_setting_sem. | ||
1892 | */ | ||
1882 | auto_remove_settings(drive); | 1893 | auto_remove_settings(drive); |
1883 | spin_unlock_irqrestore(&ide_lock, flags); | 1894 | spin_unlock_irqrestore(&ide_lock, flags); |
1884 | up(&ide_setting_sem); | 1895 | up(&ide_setting_sem); |