aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-gd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-gd.c')
-rw-r--r--drivers/ide/ide-gd.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 70aeeb18833e..70ea8763567d 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -1,4 +1,3 @@
1#include <linux/smp_lock.h>
2#include <linux/module.h> 1#include <linux/module.h>
3#include <linux/types.h> 2#include <linux/types.h>
4#include <linux/string.h> 3#include <linux/string.h>
@@ -23,6 +22,7 @@
23#define IDE_GD_VERSION "1.18" 22#define IDE_GD_VERSION "1.18"
24 23
25/* module parameters */ 24/* module parameters */
25static DEFINE_MUTEX(ide_gd_mutex);
26static unsigned long debug_mask; 26static unsigned long debug_mask;
27module_param(debug_mask, ulong, 0644); 27module_param(debug_mask, ulong, 0644);
28 28
@@ -242,9 +242,9 @@ static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode)
242{ 242{
243 int ret; 243 int ret;
244 244
245 lock_kernel(); 245 mutex_lock(&ide_gd_mutex);
246 ret = ide_gd_open(bdev, mode); 246 ret = ide_gd_open(bdev, mode);
247 unlock_kernel(); 247 mutex_unlock(&ide_gd_mutex);
248 248
249 return ret; 249 return ret;
250} 250}
@@ -257,7 +257,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
257 257
258 ide_debug_log(IDE_DBG_FUNC, "enter"); 258 ide_debug_log(IDE_DBG_FUNC, "enter");
259 259
260 lock_kernel(); 260 mutex_lock(&ide_gd_mutex);
261 if (idkp->openers == 1) 261 if (idkp->openers == 1)
262 drive->disk_ops->flush(drive); 262 drive->disk_ops->flush(drive);
263 263
@@ -269,7 +269,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
269 idkp->openers--; 269 idkp->openers--;
270 270
271 ide_disk_put(idkp); 271 ide_disk_put(idkp);
272 unlock_kernel(); 272 mutex_unlock(&ide_gd_mutex);
273 273
274 return 0; 274 return 0;
275} 275}
@@ -285,11 +285,12 @@ static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
285 return 0; 285 return 0;
286} 286}
287 287
288static int ide_gd_media_changed(struct gendisk *disk) 288static unsigned int ide_gd_check_events(struct gendisk *disk,
289 unsigned int clearing)
289{ 290{
290 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); 291 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
291 ide_drive_t *drive = idkp->drive; 292 ide_drive_t *drive = idkp->drive;
292 int ret; 293 bool ret;
293 294
294 /* do not scan partitions twice if this is a removable device */ 295 /* do not scan partitions twice if this is a removable device */
295 if (drive->dev_flags & IDE_DFLAG_ATTACH) { 296 if (drive->dev_flags & IDE_DFLAG_ATTACH) {
@@ -297,10 +298,16 @@ static int ide_gd_media_changed(struct gendisk *disk)
297 return 0; 298 return 0;
298 } 299 }
299 300
300 ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); 301 /*
302 * The following is used to force revalidation on the first open on
303 * removeable devices, and never gets reported to userland as
304 * genhd->events is 0. This is intended as removeable ide disk
305 * can't really detect MEDIA_CHANGE events.
306 */
307 ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED;
301 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; 308 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
302 309
303 return ret; 310 return ret ? DISK_EVENT_MEDIA_CHANGE : 0;
304} 311}
305 312
306static void ide_gd_unlock_native_capacity(struct gendisk *disk) 313static void ide_gd_unlock_native_capacity(struct gendisk *disk)
@@ -318,7 +325,7 @@ static int ide_gd_revalidate_disk(struct gendisk *disk)
318 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); 325 struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
319 ide_drive_t *drive = idkp->drive; 326 ide_drive_t *drive = idkp->drive;
320 327
321 if (ide_gd_media_changed(disk)) 328 if (ide_gd_check_events(disk, 0))
322 drive->disk_ops->get_capacity(drive); 329 drive->disk_ops->get_capacity(drive);
323 330
324 set_capacity(disk, ide_gd_capacity(drive)); 331 set_capacity(disk, ide_gd_capacity(drive));
@@ -340,7 +347,7 @@ static const struct block_device_operations ide_gd_ops = {
340 .release = ide_gd_release, 347 .release = ide_gd_release,
341 .ioctl = ide_gd_ioctl, 348 .ioctl = ide_gd_ioctl,
342 .getgeo = ide_gd_getgeo, 349 .getgeo = ide_gd_getgeo,
343 .media_changed = ide_gd_media_changed, 350 .check_events = ide_gd_check_events,
344 .unlock_native_capacity = ide_gd_unlock_native_capacity, 351 .unlock_native_capacity = ide_gd_unlock_native_capacity,
345 .revalidate_disk = ide_gd_revalidate_disk 352 .revalidate_disk = ide_gd_revalidate_disk
346}; 353};